您好,登錄后才能下訂單哦!
這篇文章主要講解了“以太坊DAO的概念是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“以太坊DAO的概念是什么”吧!
Decentralized Autonomous Organization,簡稱DAO,以太坊中重要的概念。一般翻譯為去中心化的自治組織。
“在區塊鏈上,沒有人知道你是一臺冰箱”——理查德布朗
到目前為止,我們列出的所有合約都是由人類持有的其他賬戶擁有和執行的。但是在以太坊生態系統中不存在對機器人或人類的歧視,合約可以像任何其他帳戶一樣創造任意行為。合約可以擁有代幣,參與眾籌,甚至是其他合約的投票成員。
在本節中,我們將建立一個去中心化的民主組織機構,僅存在于區塊鏈上,但這可以做任何簡單賬戶所能做到的事情。該組織有一個中央經理,負責決定誰是成員和投票規則,但正如我們所看到的,這也可以改變。
這種特殊民主的運作方式是它擁有一個像管理員,首席執行官或總統一樣工作的所有者Owner。所有者可以向組織添加(或刪除)投票成員。任何成員都可以提出一個提議,該提議以以太坊交易的形式發送以太或執行某些合約,其他成員可以投票支持或反對該提案。一旦預定的時間量和一定數量的成員投票,就可以執行提案:合約計票,如果有足夠的票數,它將執行給定的交易。
文末附全部代碼。
pragma solidity >=0.4.22 <0.6.0; contract owned { address public owner; constructor() public { owner = msg.sender; } modifier onlyOwner { require(msg.sender == owner); _; } function transferOwnership(address newOwner) onlyOwner public { owner = newOwner; } } contract tokenRecipient { event receivedEther(address sender, uint amount); event receivedTokens(address _from, uint256 _value, address _token, bytes _extraData); function receiveApproval(address _from, uint256 _value, address _token, bytes memory _extraData) public { Token t = Token(_token); require(t.transferFrom(_from, address(this), _value)); emit receivedTokens(_from, _value, _token, _extraData); } function () payable external { emit receivedEther(msg.sender, msg.value); } } interface Token { function transferFrom(address _from, address _to, uint256 _value) external returns (bool success); } contract Congress is owned, tokenRecipient { // Contract Variables and events uint public minimumQuorum; uint public debatingPeriodInMinutes; int public majorityMargin; Proposal[] public proposals; uint public numProposals; mapping (address => uint) public memberId; Member[] public members; event ProposalAdded(uint proposalID, address recipient, uint amount, string description); event Voted(uint proposalID, bool position, address voter, string justification); event ProposalTallied(uint proposalID, int result, uint quorum, bool active); event MembershipChanged(address member, bool isMember); event ChangeOfRules(uint newMinimumQuorum, uint newDebatingPeriodInMinutes, int newMajorityMargin); struct Proposal { address recipient; uint amount; string description; uint minExecutionDate; bool executed; bool proposalPassed; uint numberOfVotes; int currentResult; bytes32 proposalHash; Vote[] votes; mapping (address => bool) voted; } .....
打開錢包(如果你只是測試,請轉到菜單開發>網絡>testnet),轉到合約選項卡Contracts
,然后點擊部署合約deploy contract
,在solidity code box
上粘貼上面的代碼。在合約選擇器上,選擇Congress
,你將看到設置變量。
提案的最低法定人數是提案在執行之前需要的最低票數。
爭論的時間是在執行之前需要經過的最短時間(以分鐘為單位)。
多數票的保證金如果超過50%的票數加上保證金,則提案通過。在簡單多數時保留為0,將其設為成員數-1要求絕對共識。
你可以稍后更改這些參數。首先,你可以選擇5分鐘進行辯論,并將剩余參數保留為0。在頁面上稍微低一點,你將看到在以太網中部署合約的成本估算值。如果要保存,可以嘗試降低價格,但這可能意味著必須等待更長時間才能創建合約。 單擊部署Deploy
,鍵入密碼并等待。
幾秒鐘后,你將被帶到儀表板dashboard,向下滾動,你將能夠看到正在創建的交易。在不到一分鐘的時間內,你將看到交易成功,并且將創建一個新的唯一圖標。單擊合約的名稱以查看它(你可以隨時在合約選項卡Contracts
上找到它)。
如果你想與他人共享你的DAO,那么他們需要合約地址和接口文件,這是一個小文本字符串,作為合約的使用說明書。單擊復制地址copy address
以獲取前者并 顯示界面show interface
以顯示后者。
在另一臺計算機上,進入合約選項卡Contracts
,然后單擊監視合約watch contract
。添加正確的地址和界面,然后單擊OK
。
在從合約中讀取Read from contract
中,你可以看到合約中可以免費執行的所有功能,因為它們只是從區塊鏈中讀取信息。例如,你可以在此處查看合約的當前所有者owner
(應該是上載合約的帳戶)。
在寫入合約Write to contract
中,你有一個列表,其中列出了將嘗試進行某些計算以將數據保存到區塊鏈的所有函數,因此將花費以太。選擇New Proposal
,它將顯示該功能的所有選項。
在與合約交互之前,你需要添加新成員才能投票。 在Select function
選擇器上,選擇Add Member
。添加你要成為會員的人的地址(要刪除會員,請選擇Remove Member
功能)。 在execute from
時,請確保你擁有與所有者相同的帳戶,因為這只是主要管理員可以執行的操作。點擊執行execute
并等待幾秒鐘,以便下一個塊進行更改。
沒有成員列表,但你可以通過將其地址放在Read from contract
列的Members
功能上來檢查是否有人是成員。
此外,如果你想讓合約有自己的錢,你需要存入一些以太(或其他代幣),否則你將擁有一個非常無聊的組織。按右上角的transfer Ether & Tokens
。
現在讓我們將第一個提案添加到合約中。在函數選擇器上,選擇New Proposal
。
對于“受益人”,添加你要發送以太的人的地址,并在標有“Wei Amount”的框中輸入你要發送的數量。Wei是以太的最小單位,等于10^-18以太,并且必須始終作為整數給出。例如,如果要發送1以太,請輸入1000000000000000000(即18個零)。最后,添加一些描述你要執行此操作的原因的文本。暫時將“Transaction bytecode”留空。單擊執行execute
并鍵入密碼。幾秒鐘后,numProposals將增加到1,第一個提案編號0將出現在左列上。當你添加更多提案時,只需將提案編號放在proposals
字段中即可看到其中的任何提案,你可以閱讀所有提案。
投票提案也很簡單。在函數選擇器上選擇Vote
。在第一個框中鍵入提議編號,如果你同意,請選中Yes
框(或將其留空以對其進行投票)。點擊execute
發送你的投票。
投票時間過后,你可以選擇executeProposal
。如果提案只是發送以太,那么你也可以將transactionBytecode
字段留空。在點擊execute
之后但在輸入密碼之前,請注意出現的屏幕。
如果estimated fee consumption
即估計費用消耗字段上有警告,則表示由于某種原因,被調用的函數將不會執行并將突然終止。這可能意味著許多事情,但在本合約的上下文中,只要你在截止日期過后嘗試執行合約,或者用戶嘗試發送的字節碼數據與原始提案不同,就會顯示此警告。出于安全原因,如果發生任何這些事情,合約執行將突然終止,并且嘗試非法交易的用戶將失去他發送的用于支付交易費用的所有以太費用。
如果交易被執行,那么幾秒鐘之后你應該能夠看到結果:執行將變為真,并且應該從該合約的余額和收件人地址中減去正確的以太量。
你可以使用此民主方式來執行以太坊上的任何交易,只要你能夠找出該交易生成的字節碼即可。幸運的是,你可以使用錢包做到這一點!
在這個例子中,我們將使用一個代幣來表明這個合約可以容納多于以太,并且可以在任何其他基于以太坊的資產中進行交易。首先,創建一個屬于你的普通帳戶的代幣 。在合約頁面上,單擊轉移以太網和代幣以將其中一些轉移到新的congress
合約中(為簡單起見,不要將超過一半的硬幣發送到你的DAO)。之后,我們將模擬你要執行的操作。因此,如果你想建議DAO向個人發送500毫克黃金代幣作為付款,請按照你從你擁有的帳戶執行該交易的步驟,然后點擊send
但是當確認屏幕時彈出,不要輸入密碼 。
而是單擊顯示原始數據SHOW RAW DATA
鏈接并復制RAW DATA
字段上顯示的代碼并將其保存到文本文件或記事本中。取消交易。你還需要你將要為該操作調用的合約的地址,在這種情況下是代幣合約。你可以在Contracts
選項卡上找到它:將其保存在某處。
現在回到congress
合約并使用以下參數創建新提案:
作為受益人,請填寫你的代幣地址(如果它是相同的圖標請注意)。
將以太幣量留空。
在工作描述上,只需寫下你想要完成內容的描述。
在Transaction Bytecode
上 ,粘貼你在上一步中從數據字段中保存的字節碼。
幾秒鐘后,你應該能夠看到提案的詳細信息。你會注意到交易字節碼不會在那里顯示,而是只有一個交易哈希transaction hash
。與其他字段不同,字節碼可能非常冗長,因此存儲在區塊鏈上非常昂貴,因此稍后執行調用的人將提供字節碼,而不是對其進行存檔。
但是,這當然會造成一個安全漏洞:如果沒有實際代碼,投票如何投票?什么阻止用戶在提案投票后執行不同的代碼?這就是交易哈希的用武之地。在從合約中讀取read from contract
功能列表中滾動一下,你會看到一個提議檢查功能,任何人都可以放置所有的功能參數并檢查它們是否與被投票的匹配。這也保證了除非字節碼的hash與提供的代碼上的hash完全匹配,否則不會執行提議。
任何人都可以通過遵循相同的步驟來獲取正確的字節碼,然后將提議編號和其他參數添加到從合約中讀取read from contract
底部的名為 檢查提案代碼Check proposal code
的功能,從而可以非常輕松地檢查提案。
其余的投票過程保持不變:所有成員都可以投票,在截止日期之后,有人可以執行該投標。唯一的區別是,這次你必須提供之前提交的相同字節碼。注意確認窗口上的任何警告:如果它說它不會執行你的代碼,請檢查截止日期是否已經過去,是否有足夠的投票以及你的交易字節碼是否已檢出。
以下是當前DAO的一些缺點,我們將其作為練習留給讀者:
你可以將會員列表公開并編入索引嗎?
你能否允許成員改變他們的選票(在投票后但在投票結果出來之前)?
目前投票信息僅在日志上可見,你是否可以創建一個顯示所有投票的功能?
======================================================================
分享一些以太坊、EOS、比特幣等區塊鏈相關的交互式在線編程實戰教程:
java以太坊開發教程,主要是針對java和android程序員進行區塊鏈以太坊開發的web3j詳解。
python以太坊,主要是針對python工程師使用web3.py進行區塊鏈以太坊開發的詳解。
php以太坊,主要是介紹使用php進行智能合約開發交互,進行賬號創建、交易、轉賬、代幣開發以及過濾器和交易等內容。
以太坊入門教程,主要介紹智能合約與dapp應用開發,適合入門。
以太坊開發進階教程,主要是介紹使用node.js、mongodb、區塊鏈、ipfs實現去中心化電商DApp實戰,適合進階。
C#以太坊,主要講解如何使用C#開發基于.Net的以太坊應用,包括賬戶管理、狀態與交易、智能合約開發與交互、過濾器和交易等。
EOS教程,本課程幫助你快速入門EOS區塊鏈去中心化應用的開發,內容涵蓋EOS工具鏈、賬戶與錢包、發行代幣、智能合約開發與部署、使用代碼與智能合約交互等核心知識點,最后綜合運用各知識點完成一個便簽DApp的開發。
java比特幣開發教程,本課程面向初學者,內容即涵蓋比特幣的核心概念,例如區塊鏈存儲、去中心化共識機制、密鑰與腳本、交易與UTXO等,同時也詳細講解如何在Java代碼中集成比特幣支持功能,例如創建地址、管理錢包、構造裸交易等,是Java工程師不可多得的比特幣開發學習課程。
php比特幣開發教程,本課程面向初學者,內容即涵蓋比特幣的核心概念,例如區塊鏈存儲、去中心化共識機制、密鑰與腳本、交易與UTXO等,同時也詳細講解如何在Php代碼中集成比特幣支持功能,例如創建地址、管理錢包、構造裸交易等,是Php工程師不可多得的比特幣開發學習課程。
tendermint區塊鏈開發詳解,本課程適合希望使用tendermint進行區塊鏈開發的工程師,課程內容即包括tendermint應用開發模型中的核心概念,例如ABCI接口、默克爾樹、多版本狀態庫等,也包括代幣發行等豐富的實操代碼,是go語言工程師快速入門區塊鏈開發的最佳選擇。
匯智網原創翻譯,轉載請標明出處。這里是原文以太坊DAO之區塊鏈大會
附代碼:
pragma solidity >=0.4.22 <0.6.0; contract owned { address public owner; constructor() public { owner = msg.sender; } modifier onlyOwner { require(msg.sender == owner); _; } function transferOwnership(address newOwner) onlyOwner public { owner = newOwner; } } contract tokenRecipient { event receivedEther(address sender, uint amount); event receivedTokens(address _from, uint256 _value, address _token, bytes _extraData); function receiveApproval(address _from, uint256 _value, address _token, bytes memory _extraData) public { Token t = Token(_token); require(t.transferFrom(_from, address(this), _value)); emit receivedTokens(_from, _value, _token, _extraData); } function () payable external { emit receivedEther(msg.sender, msg.value); } } interface Token { function transferFrom(address _from, address _to, uint256 _value) external returns (bool success); } contract Congress is owned, tokenRecipient { // Contract Variables and events uint public minimumQuorum; uint public debatingPeriodInMinutes; int public majorityMargin; Proposal[] public proposals; uint public numProposals; mapping (address => uint) public memberId; Member[] public members; event ProposalAdded(uint proposalID, address recipient, uint amount, string description); event Voted(uint proposalID, bool position, address voter, string justification); event ProposalTallied(uint proposalID, int result, uint quorum, bool active); event MembershipChanged(address member, bool isMember); event ChangeOfRules(uint newMinimumQuorum, uint newDebatingPeriodInMinutes, int newMajorityMargin); struct Proposal { address recipient; uint amount; string description; uint minExecutionDate; bool executed; bool proposalPassed; uint numberOfVotes; int currentResult; bytes32 proposalHash; Vote[] votes; mapping (address => bool) voted; } struct Member { address member; string name; uint memberSince; } struct Vote { bool inSupport; address voter; string justification; } // Modifier that allows only shareholders to vote and create new proposals modifier onlyMembers { require(memberId[msg.sender] != 0); _; } /** * Constructor */ constructor ( uint minimumQuorumForProposals, uint minutesForDebate, int marginOfVotesForMajority ) payable public { changeVotingRules(minimumQuorumForProposals, minutesForDebate, marginOfVotesForMajority); // It’s necessary to add an empty first member addMember(address(0), ""); // and let's add the founder, to save a step later addMember(owner, 'founder'); } /** * Add member * * Make `targetMember` a member named `memberName` * * @param targetMember ethereum address to be added * @param memberName public name for that member */ function addMember(address targetMember, string memory memberName) onlyOwner public { uint id = memberId[targetMember]; if (id == 0) { memberId[targetMember] = members.length; id = members.length++; } members[id] = Member({member: targetMember, memberSince: now, name: memberName}); emit MembershipChanged(targetMember, true); } /** * Remove member * * @notice Remove membership from `targetMember` * * @param targetMember ethereum address to be removed */ function removeMember(address targetMember) onlyOwner public { require(memberId[targetMember] != 0); for (uint i = memberId[targetMember]; i<members.length-1; i++){ members[i] = members[i+1]; memberId[members[i].member] = i; } memberId[targetMember] = 0; delete members[members.length-1]; members.length--; } /** * Change voting rules * * Make so that proposals need to be discussed for at least `minutesForDebate/60` hours, * have at least `minimumQuorumForProposals` votes, and have 50% + `marginOfVotesForMajority` votes to be executed * * @param minimumQuorumForProposals how many members must vote on a proposal for it to be executed * @param minutesForDebate the minimum amount of delay between when a proposal is made and when it can be executed * @param marginOfVotesForMajority the proposal needs to have 50% plus this number */ function changeVotingRules( uint minimumQuorumForProposals, uint minutesForDebate, int marginOfVotesForMajority ) onlyOwner public { minimumQuorum = minimumQuorumForProposals; debatingPeriodInMinutes = minutesForDebate; majorityMargin = marginOfVotesForMajority; emit ChangeOfRules(minimumQuorum, debatingPeriodInMinutes, majorityMargin); } /** * Add Proposal * * Propose to send `weiAmount / 1e18` ether to `beneficiary` for `jobDescription`. `transactionBytecode ? Contains : Does not contain` code. * * @param beneficiary who to send the ether to * @param weiAmount amount of ether to send, in wei * @param jobDescription Description of job * @param transactionBytecode bytecode of transaction */ function newProposal( address beneficiary, uint weiAmount, string memory jobDescription, bytes memory transactionBytecode ) onlyMembers public returns (uint proposalID) { proposalID = proposals.length++; Proposal storage p = proposals[proposalID]; p.recipient = beneficiary; p.amount = weiAmount; p.description = jobDescription; p.proposalHash = keccak256(abi.encodePacked(beneficiary, weiAmount, transactionBytecode)); p.minExecutionDate = now + debatingPeriodInMinutes * 1 minutes; p.executed = false; p.proposalPassed = false; p.numberOfVotes = 0; emit ProposalAdded(proposalID, beneficiary, weiAmount, jobDescription); numProposals = proposalID+1; return proposalID; } /** * Add proposal in Ether * * Propose to send `etherAmount` ether to `beneficiary` for `jobDescription`. `transactionBytecode ? Contains : Does not contain` code. * This is a convenience function to use if the amount to be given is in round number of ether units. * * @param beneficiary who to send the ether to * @param etherAmount amount of ether to send * @param jobDescription Description of job * @param transactionBytecode bytecode of transaction */ function newProposalInEther( address beneficiary, uint etherAmount, string memory jobDescription, bytes memory transactionBytecode ) onlyMembers public returns (uint proposalID) { return newProposal(beneficiary, etherAmount * 1 ether, jobDescription, transactionBytecode); } /** * Check if a proposal code matches * * @param proposalNumber ID number of the proposal to query * @param beneficiary who to send the ether to * @param weiAmount amount of ether to send * @param transactionBytecode bytecode of transaction */ function checkProposalCode( uint proposalNumber, address beneficiary, uint weiAmount, bytes memory transactionBytecode ) view public returns (bool codeChecksOut) { Proposal storage p = proposals[proposalNumber]; return p.proposalHash == keccak256(abi.encodePacked(beneficiary, weiAmount, transactionBytecode)); } /** * Log a vote for a proposal * * Vote `supportsProposal? in support of : against` proposal #`proposalNumber` * * @param proposalNumber number of proposal * @param supportsProposal either in favor or against it * @param justificationText optional justification text */ function vote( uint proposalNumber, bool supportsProposal, string memory justificationText ) onlyMembers public returns (uint voteID) { Proposal storage p = proposals[proposalNumber]; // Get the proposal require(!p.voted[msg.sender]); // If has already voted, cancel p.voted[msg.sender] = true; // Set this voter as having voted p.numberOfVotes++; // Increase the number of votes if (supportsProposal) { // If they support the proposal p.currentResult++; // Increase score } else { // If they don't p.currentResult--; // Decrease the score } // Create a log of this event emit Voted(proposalNumber, supportsProposal, msg.sender, justificationText); return p.numberOfVotes; } /** * Finish vote * * Count the votes proposal #`proposalNumber` and execute it if approved * * @param proposalNumber proposal number * @param transactionBytecode optional: if the transaction contained a bytecode, you need to send it */ function executeProposal(uint proposalNumber, bytes memory transactionBytecode) public { Proposal storage p = proposals[proposalNumber]; require(now > p.minExecutionDate // If it is past the voting deadline && !p.executed // and it has not already been executed && p.proposalHash == keccak256(abi.encodePacked(p.recipient, p.amount, transactionBytecode)) // and the supplied code matches the proposal && p.numberOfVotes >= minimumQuorum); // and a minimum quorum has been reached... // ...then execute result if (p.currentResult > majorityMargin) { // Proposal passed; execute the transaction p.executed = true; // Avoid recursive calling (bool success, ) = p.recipient.call.value(p.amount)(transactionBytecode); require(success); p.proposalPassed = true; } else { // Proposal failed p.proposalPassed = false; } // Fire Events emit ProposalTallied(proposalNumber, p.currentResult, p.numberOfVotes, p.proposalPassed); } }
感謝各位的閱讀,以上就是“以太坊DAO的概念是什么”的內容了,經過本文的學習后,相信大家對以太坊DAO的概念是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。