Contract-Design

具有基於地址的授權操作的智能合約

  • January 3, 2022

我想建構一個服務,使用者可以在其中註冊(鏈下)以獲取憑據,使他們有權執行某些鏈上操作。

例如,假設我正在建構一項服務,其中有人可以通過持有我的代幣(並燒掉它,或花費它或其他任何東西)來購買我的時間,但我只希望認識我的人能夠購買代幣。所以我有一個網站,我的朋友可以給我他們的地址,然後我的代幣交易將被限制在這些地址內。

我希望這個有效所有者列表是可更新的。我怎樣才能做到這一點?

對於獎勵積分,讓我們假設白名單的變化相對頻繁。頻繁地改變契約變得昂貴。有沒有辦法更新契約本身?

您可以使用帶有修飾符的智能合約,onlyAgent其工作方式與onlyOwner(Ownable) 相同。必須通過使用該addAgent方法添加代理來批准代理。

你的合約必須繼承AgentRole

https://gist.github.com/Aboudjem/5c3dac7f227ad722791c5d9d14fdb84d

因此,您需要編寫自己的“Oracle”。您的鏈下應用程序可以收集地址,並且只有您有權訪問的管理後端可用於呼叫registerOwners契約中的函式,將地址添加到所有者列表中(確保提供一種同時停用它們的方法, 如果需要的話)。

這應該被測試,但為了節省燃料,你可以讓你的朋友呼叫一個函式,將他們的地址保存在映射中(一種預註冊),你只需呼叫一個函式來翻轉 a 中的布爾值struct,表示允許預註冊。

2022 年更新

時間流逝,經驗增加;)

您可以使用簽名消息。看看這個契約: https ://etherscan.io/address/0xF2Bce1776A49250A5cad0F81aeb5C21Be72F537a#code

在第 374 行(文件 1,共 21 個):

function mintById_SignedMessage(uint256 _tokenId, uint256 _setPrice, uint256 expirationTimestamp, uint256 _nonce, bytes memory _sig) public payable{
       // check validity and execute
       require(expirationTimestamp <= block.timestamp, "Expired");
       bytes32 message = SignedMessages.prefixed(keccak256(abi.encodePacked(msg.sender, _tokenId, _setPrice, expirationTimestamp, _nonce)));
       require(msg.value == _setPrice, "Wrong payment");
       require(SignedMessages.consumePass(message, _sig, _nonce), "Error in signed msg");
       _internalMintById(msg.sender, _tokenId);
       if (msg.value > 0) {
           emit FundsReceived(msg.sender, msg.value, "payment by minting sale");
       }
   }

通過傳遞所謂的“鑄幣通行證”來呼叫此函式。前往第 3 個文件,共 21 個文件:這是檢查簽名的契約。因此,呼叫參數使用有效的“發行者”鏈下(由您)的私鑰進行簽名。然後你將這個簽名消息提供給使用者(例如通過前端或後端),當他們呼叫合約時,他們可以提供那個簽名消息。你的合約可以驗證它是由正確的發行者發行的,如下所示:

function consumePass(bytes32 message, bytes memory sig, uint256 nonce) internal returns(bool){
   // check the nonce first
   if (nonces[nonce]) {
       return false;
   }
   // check the issuer
   if (!issuers[recoverSigner(message, sig)]) {
       return false;
   }
   // consume the nonce if it is safe
   nonces[nonce] = true;
   return true;
}

一些進一步的連結:

引用自:https://ethereum.stackexchange.com/questions/35692