區塊鏈民主 - 如何開發透過投票執行的合約

買賣虛擬貨幣
當你為某事投贊成票時,你如何知道實際上會完成什麼事情?你怎麼知道承諾會兌現?在本文中,我將簡要介紹區塊鏈如何改變民主。如何透過區塊鏈民主程式,把承諾變成了行動。我並不是要說我們可以或應該廢除政治並建立技術專家制,但是我將展示如何執行一個投票系統,如果投票透過,該系統將自動制定執行。你可以稱之為不可阻擋的民主。概念設計首先,請讓我以兩種智慧合約來設定場景:
· 智慧合約是一個不可變的程式。智慧合約中編碼好的規則無法更改。部署後,也無法停止。· 智慧合約還可以觸發其他智慧合約的操作。例如,智慧合約可以觸發另一個合約以將資金釋放到某個帳戶,或授予某人執行某些交易的許可權。根據這些概念,我們可以編寫執行公平投票程式的智慧合約。每個人都能看到的明確規則, 在該智慧合約中,我們可以包含一個提案,該提案是對另一個智慧合約中的功能的呼叫。無論如何,投票都會進行。如果投票透過,無論如何都將執行該提案。以太坊和民主投票是民主的支柱之一,也是以太坊的核心組成部分之一。
通常認為Vitalik Buterin[3]突破了比特幣,提議以太坊上建立一個平臺,允許在該平臺上使用我們上面描述的原則來實施民主組織。這些基於區塊鏈的民主組織被稱為去中心化自治組織[4],簡稱DAO(Decentralized Autonomous Organizations)。DAO由其利益相關者指導,規則編碼在區塊鏈智慧合約中,沒有中心控制。當你對某事投票時,你如何知道實際上會完成什麼事情?你怎麼知道承諾會兌現?閱讀DAO的維基百科文章[5]非常有趣。它揭示了早期DAO的概念是如何構思的,以及它是多麼的強大。Daniel Larimer[6](他由BitShares,Steem和EOS.IO專案成名)提出並 最早於2013年在BitShares 實現了該概念。然後你也知道The DAO(Đ)[7],該組織在遭到駭客入侵[8]前吸引到了所有流通中的14%的以太幣投資到該組織中。但是, “The DAO” 的消亡並不意味著“ DAO組織”的消亡。去中心化自治組織還活著並且很好[9],因為死亡的 The DAO的漏洞已廣為人知,而且很容易避免。Vlad Farcas[10]和我開始了一個玩具DAO專案[11],因為我們想學習如何應用民主模式。透過編寫DAO,我瞭解了區塊鏈中民主流程的可能性,這讓我大吃一驚。這就是為什麼我要寫這個。
介紹結束,讓我們深入研究程式碼。我們應該怎麼做?制定智慧合約提案考慮以下合約:contract Proposal {  address public targetContract;  bytes public targetCall;
  /// @param targetContract_ 執行提案的目標合約  /// @param targetCall_ 執行提案的目標函式(abi 編碼及引數)  constructor(    address targetContract_,    bytes memory targetCall_,  ) public {
    targetContract = targetContract_;    proposalData = targetCall_;  }  /// @dev 執行投票的提案  function enact() external virtual {    (bool success, ) = targetContract.call(targetCall);
    require(success, “Failed to enact proposal.”);  }}該合約具有一些底層的魔法,但解釋起來並不難。在部署時,它需要另一個合約的地址和一個函式呼叫。呼叫enact()時,它將在目標合約上執行函式呼叫。可以使用web3.js[12]對提案進行編碼。在javascript中,下面的示例中部署了一個提案,該提案在執行時將鑄造一個ERC20代幣。token = await ERC20Mintable.new(‘Token’, ‘TKN’, 18);
proposalData = web3.eth.abi.encodeFunctionCall(  {    type: ‘function’,    name: ‘mint’,    payable: false,    inputs: [
      {name: ‘account’, type: ‘address’},      {name: ‘amount’, type: ‘uint256’},    ],  },  [owner, ‘1’]);
proposal = await Proposal.new(token.address, proposalData);web3.eth.abi.encodeFunctionCall有點冗長,但實際上唯一做的就是將函式簽名和引數包裝在32個位元組的資料中(參考文件[13])。它的第一個參數列示函式簽名,稱為mint(鑄幣函式),是非付費的函式,其address引數稱為account,另一個uint256引數稱為amount。第二個引數則是為引數賦值,使用在其他地方定義的owner帳戶,而鑄幣的數量為1。有更簡單的方法可以讓一個合約呼叫在另一個合約上的函式。現在也許很難理解為什麼我們會以這種複雜的方式來做這件事情。繼續閱讀,現在我們將使該提案民主化。讓我們看看制定提案的合約,它需要經過成功的投票之後執行。一幣一票
你可以在HQ20程式碼庫中找到此合約[14]程式碼,請隨意使用它,但不要不加修改的用於現實產品中。為了易於理解,我們忽略了許多對漏洞的處理,例如針對閃貸攻擊的漏洞。pragma solidity ^0.6.0;import "@openzeppelin/contracts/access/Ownable.sol";import "@openzeppelin/contracts/token/ERC20/IERC20.sol";import "../math/DecimalMath.sol";contract OneTokenOneVote is Ownable {
    using DecimalMath for uint256;    event VotingCreated();    event VotingValidated();    event ProposalEnacted();    event VoteCasted(address voter, uint256 votes);    event VoteCanceled(address voter, uint256 votes);
    IERC20 public votingToken;    mapping(address => uint256) public votes;    address public targetContract;    bytes public proposalData;    uint256 public threshold;    bool public passed;
    constructor(        address _votingToken,        address _targetContract,        bytes memory _proposalData,        uint256 _threshold    ) public Ownable() {
        votingToken = IERC20(_votingToken);        threshold = _threshold;        targetContract = _targetContract;        proposalData = _proposalData;        emit VotingCreated();    }
    modifier proposalPassed() {        require(passed == true, "Cannot execute until vote passes.");        _;    }    /// @dev Function to enact one proposal of this voting.    function enact() external virtual proposalPassed {
        // solium-disable-next-line security/no-low-level-calls        (bool success, ) = targetContract.call(proposalData);        require(success, "Failed to enact proposal.");        emit ProposalEnacted();    }    /// @dev 用這個函式投票,需要先授權
    /// (from the frontend) to spend _votes of votingToken tokens.    /// @param _votes The amount of votingToken tokens that will be casted.    function vote(uint256 _votes) external virtual {        votingToken.transferFrom(msg.sender, address(this), _votes);        votes[msg.sender] = votes[msg.sender].addd(_votes);        emit VoteCasted(msg.sender, _votes);
    }    /// @dev Use this function to retrieve your votingToken votes in case you changed your mind or the voting has passed    function cancel() external virtual {        uint256 count = votes[msg.sender];        delete votes[msg.sender];        votingToken.transfer(msg.sender, count);
        emit VoteCanceled(msg.sender, count);    }    /// @dev Number of votes casted in favour of the proposal.    function inFavour() public virtual view returns (uint256) {        return votingToken.balanceOf(address(this));    }
    /// @dev Number of votes needed to pass the proposal.    function thresholdVotes() public virtual view returns (uint256) {        return votingToken.totalSupply().muld(threshold, 4);    }    /// @dev Function to validate the threshold    function validate() public virtual {
        require(            inFavour() >= thresholdVotes(),            "Not enough votes to pass."        );        passed = true;        emit VotingValidated();
    }}在 OneTokenOneVote.sol 檔案裡:· 投票的代幣,是來自部署時選擇的ERC20合約。· 投票意味著使用vote()將代幣轉移到OneTokenOneVote合約中。· 如果在任何時候OneTokenOneVote持有的比例高於threshold (相比於流通量),則透過提案。
· 提案透過後,它將永遠保持在 passed 狀態。· 選民可以隨時取消投票(呼叫 cancel)並取回其代幣,但如果他們希望提案透過,則應在提案透過後再進行取回。· 任何人都可以透過呼叫validate()來觸發計票。如果達到threshold,這將使投票透過。實現投票有幾種方法[15]。有更安全的投票方式,包括要求達到法定人數。OneTokenOneVote.sol 是我們能想到的最簡單的示例,但這足以顯示區塊鏈民主的原理。在部署投票合約時,它接受帶有引數編碼的 targetContract 和targetFunction作為提案。如果投票透過,任何人都可以呼叫 enact() 函式來執行提案。這意味著投票合約包括如果表決透過將要採取的行動。不可能忽略投票結果。在區塊鏈之前這是不可能的,請思考一下。
合約民主我們可以為這種區塊鏈民主概念提供另一種轉折。到目前為止,我們知道如何部署需要執行表決過程然後在執行投票結果結果的合約。我們可以編寫一份合約,其中所有的功能如果經過表決就才能被執行。這就是DAO的精神,它比聽起來容易。在程式碼庫中,我們包含了第三份合約Democratic.sol[16],我發現使用起來真的很令人興奮。它允許任何合約對是否執行其任何功能進行表決。· Democratic.sol被設計為可被其他合約繼承,僅當它們經過投票後才允許將其中函式可執行。你可以透過使用 onlyProposal 來修飾要執行的函式來做到這一點。· Democratic.sol允許任何人提出提案進行投票。propose() 函式可以被任何人使用,目標函式使用 web3.eth.abi.encodeFunctionCall 編碼。
· 所有提案的投票代幣都將相同,從而在MakerDAO[17]中建立一個帶有MKR代幣的社羣。Democratic.sol 的實現是基於代幣的投票,但可以輕鬆更改為基於帳戶的投票。· 全部提案儲存在 proposals 變數中,並且只有由同一合約建立的提案才能執行標記為onlyProposal的函式。如果考慮到這一點,則可以使用Democratic.sol和OneTokenOneVote.sol作為[完整民主系統的基礎](https://github.com/HQ20/contracts/blob/master/contracts/access /Democracy.sol "完整民主系統的基礎")。如果你沒有發現這是多麼的令人興奮,我不知道還能告訴你什麼。結論區塊鏈有可能以我們一生中從未有過的程度改變民主程序。使用區塊鏈可以實現不可阻擋的投票,一旦投票透過,任何人都無法避免被執行。隨著越來越多的世界可以從區塊鏈訪問,民主的力量將會增長。
在本文中,我們展示瞭如何實現智慧合約執行的投票程式,並對其進行了改進,以生成只能由民主程序執行的智慧合約函式。自從以太坊誕生以來,這些概念在區塊鏈生態系統中都不是新事物。但是,在這些合約中,我們提供的基礎模組往前民主又邁出了一步。參考資料[1]登鏈翻譯計劃: https://github.com/lbc-team/Pioneer[2]Tiny熊: https://learnblockchain.cn/people/15[3]Vitalik Buterin: https://about.me/vitalik_buterin
[4]去中心化自治組織: https://en.wikipedia.org/wiki/Decentralized_autonomous_organization[5]DAO的維基百科文章: https://en.wikipedia.org/wiki/Decentralized_autonomous_organization[6]Daniel Larimer: https://twitter.com/bytemaster7[7]The DAO(Đ): https://en.wikipedia.org/wiki/The_DAO_%28organization%29[8]遭到駭客入侵: https://medium.com/swlh/the-story-of-the-dao-its-history-and-consequences-71e6a8a551ee[9]還活著並且很好: https://defirate.com/daos/
[10]Vlad Farcas: https://twitter.com/uivlis[11]玩具DAO專案: https://github.com/HQ20/contracts/tree/master/contracts/examples/dao[12]web3.js: https://learnblockchain.cn/docs/web3.js/web3-eth-abi.html#encodefunctioncall[13]參考文件: https://learnblockchain.cn/docs/web3.js/web3-eth-abi.html#encodefunctioncall[14]HQ20程式碼庫中找到此合約: https://github.com/HQ20/contracts/blob/master/contracts/voting/OneTokenOneVote.sol[15]幾種方法: https://github.com/HQ20/contracts/blob/master/contracts/voting/OneManOneVote.sol
[16]Democratic.sol: https://github.com/HQ20/contracts/blob/master/contracts/voting/Democratic.sol[17]MakerDAO: http://makerdao.com/[18]Cell Network: https://www.cellnetwork.io/?utm_souce=learnblockchain[19]Alberto Cuesta Cañada: https://medium.com/@albertocuestacanada?source=post_page-----932b969d1cc5

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;