本文小編為大家詳細(xì)介紹“以太坊DAO時(shí)間鎖定Multisig怎么運(yùn)用”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“以太坊DAO時(shí)間鎖定Multisig怎么運(yùn)用”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。
創(chuàng)新互聯(lián)建站專注于錫林郭勒盟網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供錫林郭勒盟營(yíng)銷型網(wǎng)站建設(shè),錫林郭勒盟網(wǎng)站制作、錫林郭勒盟網(wǎng)頁(yè)設(shè)計(jì)、錫林郭勒盟網(wǎng)站官網(wǎng)定制、小程序開發(fā)服務(wù),打造錫林郭勒盟網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供錫林郭勒盟網(wǎng)站排名全網(wǎng)營(yíng)銷落地服務(wù)。
Decentralized Autonomous Organization,簡(jiǎn)稱DAO,以太坊中重要的概念。一般翻譯為去中心化的自治組織。
有時(shí)候,時(shí)間也可以用作一種很好的安全機(jī)制。以下代碼基于DAO區(qū)塊鏈大會(huì),但有不同的變化。不是每個(gè)操作需要X個(gè)成員批準(zhǔn),而是任何交易都可以由單個(gè)成員發(fā)起,但它們?cè)趫?zhí)行之前都需要最少的延遲,這取決于交易的支持。提案的批準(zhǔn)越多,就越早執(zhí)行。會(huì)員可以對(duì)交易進(jìn)行投票,這意味著它將取消其他一個(gè)已批準(zhǔn)的簽名。
這意味著如果你沒(méi)有緊急程度,則執(zhí)行任何交易可能只需要一個(gè)或兩個(gè)簽名。但是,如果單個(gè)密鑰被泄露,其他密鑰可以將該交易延遲數(shù)月或數(shù)年,甚至可以阻止其執(zhí)行。
所有密鑰都已批準(zhǔn)的交易可以在十分鐘后執(zhí)行(此金額是可配置的),并且每5%未投票的成員每次需要的時(shí)間加倍(如果他們主動(dòng)投票,則為四倍)反對(duì))。如果它是一個(gè)簡(jiǎn)單的ether交易,只要支持投票將其置于所需的時(shí)間內(nèi),就會(huì)執(zhí)行交易,但更復(fù)雜的交易將要求使用正確的字節(jié)碼手動(dòng)執(zhí)行交易。這些是默認(rèn)值,但在創(chuàng)建合約時(shí)可以設(shè)置不同的值:
批準(zhǔn)交易的成員數(shù)量:近似時(shí)間延遲
100%批準(zhǔn):10分鐘(最低默認(rèn)值)
90%批準(zhǔn):40分鐘
80%:2小時(shí)40分鐘
50%:大約一周
40%:1個(gè)月
30%:4個(gè)月
20%:超過(guò)一年
10%或更少:5年或從不 一旦最短的時(shí)間過(guò)去,任何人都可以執(zhí)行交易(參見(jiàn)“國(guó)會(huì)”以獲得更完整的步行)。這是故意的,因?yàn)樗试S某人安排交易或雇用其他人來(lái)執(zhí)行交易。
代碼:
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 TimeLockMultisig is owned, tokenRecipient { Proposal[] public proposals; uint public numProposals; mapping (address => uint) public memberId; Member[] public members; uint minimumTime = 10; event ProposalAdded(uint proposalID, address recipient, uint amount, string description); event Voted(uint proposalID, bool position, address voter, string justification); event ProposalExecuted(uint proposalID, int result, uint deadline); event MembershipChanged(address member, bool isMember); struct Proposal { address recipient; uint amount; string description; bool executed; int currentResult; bytes32 proposalHash; uint creationDate; 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 * * First time setup */ constructor( address founder, address[] memory initialMembers, uint minimumAmountOfMinutes ) payable public { if (founder != address(0)) owner = founder; if (minimumAmountOfMinutes !=0) minimumTime = minimumAmountOfMinutes; // 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'); changeMembers(initialMembers, true); } /** * Add member * * @param targetMember address to add as a member * @param memberName label to give this member address */ function addMember(address targetMember, string memory memberName) onlyOwner public { uint id; if (memberId[targetMember] == 0) { memberId[targetMember] = members.length; id = members.length++; } else { id = memberId[targetMember]; } members[id] = Member({member: targetMember, memberSince: now, name: memberName}); emit MembershipChanged(targetMember, true); } /** * Remove member * * @param targetMember the member to remove */ 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--; } /** * Edit existing members * * @param newMembers array of addresses to update * @param canVote new voting value that all the values should be set to */ function changeMembers(address[] memory newMembers, bool canVote) public { for (uint i = 0; i < newMembers.length; i++) { if (canVote) addMember(newMembers[i], ''); else removeMember(newMembers[i]); } } /** * 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.executed = false; p.creationDate = now; emit ProposalAdded(proposalID, beneficiary, weiAmount, jobDescription); numProposals = proposalID+1; vote(proposalID, true, ''); 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 { Proposal storage p = proposals[proposalNumber]; // Get the proposal require(p.voted[msg.sender] != true); // If has already voted, cancel p.voted[msg.sender] = true; // Set this voter as having voted 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); // If you can execute it now, do it if ( now > proposalDeadline(proposalNumber) && p.currentResult > 0 && p.proposalHash == keccak256(abi.encodePacked(p.recipient, p.amount, '')) && supportsProposal) { executeProposal(proposalNumber, ''); } } function proposalDeadline(uint proposalNumber) public view returns(uint deadline) { Proposal storage p = proposals[proposalNumber]; uint factor = calculateFactor(uint(p.currentResult), (members.length - 1)); return p.creationDate + uint(factor * minimumTime * 1 minutes); } function calculateFactor(uint a, uint b) public pure returns (uint factor) { return 2**(20 - (20 * a)/b); } /** * 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 >= proposalDeadline(proposalNumber) // If it is past the voting deadline && p.currentResult > 0 // and a minimum quorum has been reached && !p.executed // and it is not currently being executed && checkProposalCode(proposalNumber, p.recipient, p.amount, transactionBytecode)); // and the supplied code matches the proposal... p.executed = true; (bool success, ) = p.recipient.call.value(p.amount)(transactionBytecode); require(success); // Fire Events emit ProposalExecuted(proposalNumber, p.currentResult, proposalDeadline(proposalNumber)); } }
像以前一樣在這些教程上部署該代碼。在部署參數(shù)上,將最小時(shí)間留空將默認(rèn)為30分鐘,如果你想要更快的鎖定時(shí)間,則放1分鐘。上傳后,執(zhí)行“添加成員”功能以添加組的新成員,他們可以是你認(rèn)識(shí)的其他人,也可以是不同計(jì)算機(jī)上的帳戶或離線存儲(chǔ)。
設(shè)置為所有者owner的帳戶非常強(qiáng)大,因?yàn)樗梢噪S意添加或刪除成員。因此,在添加主成員后,我們建議你通過(guò)執(zhí)行Transfer Membership
功能將owner
設(shè)置為另一個(gè)帳戶。如果你希望對(duì)所有成員的添加或刪除進(jìn)行投票,則將其設(shè)置為multisig本身,就像任何其他交易一樣。另一種方法是將其設(shè)置為另一個(gè)受信任的multisig
錢包,如果你希望永久修復(fù)成員數(shù),則可以設(shè)置為0x000。請(qǐng)記住,此合約上的資金僅與“所有者”帳戶一樣安全。
與上述任何DAO一樣,此合約可以持有以太幣,任何基于以太坊的代幣并執(zhí)行任何合約。為此,請(qǐng)檢查如何在國(guó)會(huì)DAO上執(zhí)行復(fù)雜的提案。
為簡(jiǎn)單起見(jiàn),對(duì)提案的投票僅僅算得少一點(diǎn)支持。如果你愿意,你可以玩弄負(fù)面投票更重要的想法,但這意味著少數(shù)成員可以對(duì)任何提議的交易擁有有效的否決權(quán)!
讀到這里,這篇“以太坊DAO時(shí)間鎖定Multisig怎么運(yùn)用”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
分享名稱:以太坊DAO時(shí)間鎖定Multisig怎么運(yùn)用
文章源于:http://aaarwkj.com/article44/gdijee.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)、用戶體驗(yàn)、品牌網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè)、ChatGPT、網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)