Solidity合約代理模式的簡(jiǎn)單示例

一祝闻、概述

這個(gè)合約示例中占卧,我們有以下幾個(gè)文件:

Types.sol
IProcessor.sol
Processor.sol
Proxy.sol
Client.sol

分別論述下文件的作用:
Types.sol定義了一些基本類型,與業(yè)務(wù)邏輯無(wú)關(guān)联喘;
IProcessor.sol:關(guān)鍵合約屉栓,定義了Processor的接口;
Processor.sol:關(guān)鍵合約耸袜,定義了實(shí)際對(duì)數(shù)據(jù)的邏輯操作;
Proxy.sol:關(guān)鍵合約牲平,定義了數(shù)據(jù)以及邏輯操作合約Processor的地址堤框;
Client.sol定義了用戶操作Proxy合約的方法,免去手動(dòng)將IProcessor賦予Proxy的過(guò)程纵柿。

1.Types.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

enum Gender {
    Male,
    Female
}

struct Student {
    string name;
    Gender gender;
    uint256 age;
}

2.IProcessor.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import {Gender} from "./Types.sol";

interface IProcessor {
    function setStudentName(string memory) external;
    function setStudentGender(Gender) external;
    function setStudentAge(uint256) external;
}

3.Processor.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "./IProcessor.sol";
import {Gender, Student} from "./Types.sol";

contract Processor is IProcessor {
    Student public student;
    address public processor;

    function setStudentName(string calldata _name) override external {
        student.name = _name;
    }

    function setStudentGender(Gender _gender) override external {
        student.gender = _gender;
    }

    function setStudentAge(uint256 _age) override external {
        student.age = _age;
    }
}

4.Proxy.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "./IProcessor.sol";
import {Student} from "./Types.sol";

contract Proxy {
    Student public student;
    address public processor;

    function setProcessor(address _processor) external {
        processor = _processor;
    }

    fallback() external payable  {
        (bool success, bytes memory data) = processor.delegatecall(msg.data);
        require(
            success,
            "error"
        );
    }
}

5.Client.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "./IProcessor.sol";
import {Gender, Student} from "./Types.sol";

contract Client {
    IProcessor ip;

    constructor(address _proxy) {
        ip = IProcessor(_proxy);
    }

    function setName(string calldata _name) external {
        ip.setStudentName(_name);
    } 

    function setGender(Gender _gender) external {
        ip.setStudentGender(_gender);
    }

    function setAge(uint256 _age) external {
        ip.setStudentAge(_age);
    }
}

我們用Client進(jìn)行操作蜈抓,比如說(shuō),執(zhí)行setName函數(shù)昂儒,輸入的參數(shù)為字符串Tom沟使,接下來(lái),就是觸發(fā)IProcessor類型的代理合約Proxy去執(zhí)行setStudentName渊跋,但事實(shí)上腊嗡,代理合約中并沒(méi)有setStudentName,因此會(huì)去執(zhí)行fallback函數(shù)拾酝,fallback函數(shù)中有關(guān)鍵的delegatecall函數(shù)燕少,它會(huì)委托Processor合約去執(zhí)行setStudentName的函數(shù)邏輯,但是改變的是Proxy合約上的student值蒿囤。這樣就實(shí)現(xiàn)了數(shù)據(jù)邏輯的分離客们。下次如果我們需要升級(jí)邏輯處理合約就非常簡(jiǎn)單了——在Proxy中,使用setProcessor函數(shù)將舊的Processor合約替換成新的Processor合約即可材诽。

二底挫、缺陷

這個(gè)實(shí)現(xiàn)主要有兩個(gè)缺陷。

  • 其一是Proxy中的fallback函數(shù)執(zhí)行delegatecall后脸侥,有兩個(gè)返回值建邓,一個(gè)是bool類型的success,一個(gè)是bytes類型的data湿痢。這個(gè)示例中我們的Processor合約中的函數(shù)沒(méi)有返回值涝缝,倒無(wú)所謂扑庞,如果有返回值的話,我們其實(shí)是需要返回給調(diào)用者的拒逮。
  • 其二是為了使得delegatecall的順利執(zhí)行罐氨,ProxyProcessor兩個(gè)合約保持了相同的變量存儲(chǔ)結(jié)構(gòu),但實(shí)際執(zhí)行時(shí)Processor中的變量卻僅僅是擺設(shè)滩援,這樣的設(shè)計(jì)就顯得累贅栅隐,不夠優(yōu)雅。

這兩個(gè)問(wèn)題其實(shí)都有解決方案玩徊,請(qǐng)看下一篇:《Solidity合約代理模式的幾個(gè)技術(shù)技巧》租悄。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市恩袱,隨后出現(xiàn)的幾起案子泣棋,更是在濱河造成了極大的恐慌,老刑警劉巖畔塔,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件潭辈,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡澈吨,警方通過(guò)查閱死者的電腦和手機(jī)把敢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)谅辣,“玉大人修赞,你說(shuō)我怎么就攤上這事∩=祝” “怎么了柏副?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)蚣录。 經(jīng)常有香客問(wèn)我搓扯,道長(zhǎng),這世上最難降的妖魔是什么包归? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任锨推,我火速辦了婚禮,結(jié)果婚禮上公壤,老公的妹妹穿的比我還像新娘换可。我一直安慰自己,他們只是感情好厦幅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布沾鳄。 她就那樣靜靜地躺著,像睡著了一般确憨。 火紅的嫁衣襯著肌膚如雪译荞。 梳的紋絲不亂的頭發(fā)上瓤的,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音吞歼,去河邊找鬼圈膏。 笑死,一個(gè)胖子當(dāng)著我的面吹牛篙骡,可吹牛的內(nèi)容都是我干的稽坤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼糯俗,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼尿褪!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起得湘,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤杖玲,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后淘正,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體天揖,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年跪帝,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片些阅。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡伞剑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出市埋,到底是詐尸還是另有隱情黎泣,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布缤谎,位于F島的核電站抒倚,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏坷澡。R本人自食惡果不足惜托呕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望频敛。 院中可真熱鬧项郊,春花似錦、人聲如沸斟赚。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)拗军。三九已至任洞,卻和暖如春蓄喇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背交掏。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工妆偏, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人耀销。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓楼眷,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親熊尉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子罐柳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 本文翻譯自Zeppelin于2018年發(fā)表的關(guān)于《代理模式》文章。所有權(quán)歸原文作者所有狰住。原文鏈接:https://...
    六天天天向上閱讀 1,147評(píng)論 0 2
  • 以太坊最大的優(yōu)勢(shì)就是张吉,每一筆用來(lái)轉(zhuǎn)賬、部署合約或者和合約交互的交易(事務(wù))都被存在一個(gè)叫做區(qū)塊鏈的公共賬本上催植。一旦...
    王鐵塔閱讀 1,496評(píng)論 0 0
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理肮蛹,服務(wù)發(fā)現(xiàn),斷路器创南,智...
    卡卡羅2017閱讀 134,654評(píng)論 18 139
  • 鉆石標(biāo)準(zhǔn)主要是為了對(duì)應(yīng)以太坊上智能合約大小24K字節(jié)的限制伦忠。同時(shí)也可以應(yīng)用來(lái)處理智能合約的無(wú)縫升級(jí)問(wèn)題。鉆石合約是...
    末座少年閱讀 999評(píng)論 0 1
  • 背景:由于公鏈環(huán)境下所有的信息都是共享的稿辙,智能合約相當(dāng)于是完全透明化昆码,任何人都可以調(diào)用,外加一些利益的驅(qū)動(dòng)邻储,導(dǎo)致引...
    95加不滿閱讀 848評(píng)論 0 1