標籤:immediate poi 子集 集合 min 根據 ESS 不容易 miner
最近考慮一個基於以太坊的去中心化du-場的實現,du-場如果需要實現,那麼隨機數是必須的。然後研究了一下以太坊裡面的隨機數產生,發現並不容易。
eth裡面產生隨機數的幾種方式。
oraclize
Oraclize定位為去中心化應用的資料搬運工,他作為Web APIs和DApp的可靠連結。有了Oraclize,
就不需要建立額外的信任鏈結,因為我們的行為已經被強制加密驗證。Oraclize是一個可證明的誠實的預言機服務,
可以讓智能合約可以訪問互連網。Oraclize是平台無關的,為所有主流的智能合約能力平台提供一種虛擬介面。可以想像,
通過這個投入成千上萬的有意義的資料到區塊鏈中,可以使得智能合約產業更繁榮和更多有價值的應用呈現更大的生命力。
Oraclize的使用方式可以參考下面的[代碼]
(github.com/oraclize/ethereum-examples/blob/master/solidity/random-datasource/randomExample.sol)
在update方法裡面調用oraclize_newRandomDSQuery方法來調用Oracle的智能合約的代碼,
Oracle根據請求來產生對應的資料, 然後把結果通過回調__callback來傳入。
????/
???? Oraclize random-datasource example
????
???? This contract uses the random-datasource to securely generate off-chain N random bytes
????/
????
????pragma solidity ^0.4.11;
????
????import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";
????
????contract RandomExample is usingOraclize {
????
???? event newRandomNumber_bytes(bytes);
???? event newRandomNumber_uint(uint);
????
???? function RandomExample() {
???? oraclize_setProof(proofType_Ledger); // sets the Ledger authenticity proof in the constructor
???? update(); // let‘s ask for N random bytes immediately when the contract is created!
???? }
????
???? // the callback function is called by Oraclize when the result is ready
???? // the oraclize_randomDS_proofVerify modifier prevents an invalid proof to execute this function code:
???? // the proof validity is fully verified on-chain
???? function callback(bytes32 _queryId, string _result, bytes _proof)
???? {
???? // if we reach this point successfully, it means that the attached authenticity proof has passed!
???? if (msg.sender != oraclize_cbAddress()) throw;
????
???? if (oraclize_randomDS_proofVerifyreturnCode(_queryId, _result, _proof) != 0) {
???? // the proof verification has failed, do we need to take any action here? (depends on the use case)
???? } else {
???? // the proof verification has passed
???? // now that we know that the random number was safely generated, let‘s use it..
????
???? newRandomNumber_bytes(bytes(_result)); // this is the resulting random number (bytes)
????
???? // for simplicity of use, let‘s also convert the random bytes to uint if we need
???? uint maxRange = 2*(8 7); // this is the highest uint we want to get. It should never be greater than 2^(8*N), where N is the number of random bytes we had asked the datasource to return
???? uint randomNumber = uint(sha3(_result)) % maxRange; // this is an efficient way to get the uint out in the [0, maxRange] range
????
???? newRandomNumber_uint(randomNumber); // this is the resulting random number (uint)
???? }
???? }
????
???? function update() payable {
???? uint N = 7; // number of random bytes we want the datasource to return
???? uint delay = 0; // number of seconds to wait before the execution takes place
???? uint callbackGas = 200000; // amount of gas we want Oraclize to set for the callback function
???? bytes32 queryId = oraclize_newRandomDSQuery(delay, N, callbackGas); // this function internally generates the correct oraclize_query and returns its queryId
???? }
????
????}
考慮一個提供打du的智能合約。
使用者調用打du的介面,這個介面會把使用者的請求儲存起來,然後調用Oracle隨機數產生服務。
然後通過Oracle回調服務,判斷隨機數是否大於某個值,如果成立,那麼使用者成功,否則使用者失敗。
這就是典型的Oracle的使用案例。
RANDAO: A DAO working as RNG of Ethereum
randao是一個產生以太坊隨機數的去中心化組織,
Random number in programming is very important!
RNG in a deterministic system is very difficult
Miners can‘t be trusted!
隨機數在編程中是非常重要的。
RNG 在一個確定性系統中是非常難的。
不能相信礦工
解決方案
Solutions
A DAO (decentralised autonomous organisation) that anyone can participate in, and the random number is generated by all participants together! First of all, we need to create a RANDAO contract in the blockchain, which defines the participation rules. Then the basic process of generating a random number can be divided into three phases:
一個DAO(去中心化的匿名組織)允許任何人加入,隨機數是被所有的參與者一起合作產生的。首先,我們需要在區塊鏈上建立一個RANDAO的智能合約,合約定義了參與規則。然後產生隨機數的基本過程可以分為下面三個步驟:
The first phase: collecting valid sha3(s)
Anyone who want to participate in the random number generation needs to send a transaction to the contract C with m ETH as pledge in a specified time period (e.g, 6 block period, approximately 72s), accompanied by the result of sha3(s), s is the secret number respective picked by participant.
第一步:收集有效sha3(s)
參與隨機數產生的參與者首先需要在一個指定的時間區間(比如,6個區塊的區間,大約72秒)發送m ETH作為抵押到智能合約 C,同時發送一個sha3(s)的值到智能合約C ,s是一個只有參與者自己知道的數字.
The second phase: collecting valid s
After the first phase, anyone who submitted sha3(s) successfully needs to send a transaction with the secret number s in the first stage to contract C within a specified time period. Contract C will check if s is valid by running sha3 against s and comparing the result with previous committed data. Valid s will be saved to the collection of seeds to finally generate the random number.
第二步:收集有效s
在第一步結束後,那些提交了sha3(s)的參與者需要在指定的時間區間內發送s到智能合約C. 智能合約C會檢查sha3(s)和之前提交的值是否相同。 相同的s會被儲存到種子集合用來最終產生隨機數。
The third phase: calculating a random number, refund pledged ETH and bonus
- After all secret numbers have been successfully collected, contract C will calculate the random number from the function f(s1,s2,...,sn), the result will be written to the storage of C, and the result will be sent to all other contracts that requested the random number before.
- Contract C will send back the pledge to the participants in the first phase, and the profit is divided into equal parts and sent to all participants as an additional bonus. The profit comes from the fees that is paid by other contracts that consume the random number.
第三步:計算隨機數,退回抵押和獎金
- 在所有的秘密數字s被成功收集後,智能合約C會使用函數f(s1,s2,...,sn)來計算隨機數,隨機數的結果會寫入智能合約的儲存,而且結果會被發送到所有之前請求隨機數的其他智能合約上面。
- 智能合約C會把第一階段的抵押返回給參與者,然後獎金會被分成同等分發送給所有的參與者。獎金來源於請求隨機值的其他智能合約。
Additional rules
In order to ensure the RNG can‘t be manipulated, as well as for safety and efficiency, the contract C has the following additional rules:
The first phase, if two or more of the same sha3(s) are submitted in sequence, only the first one is accepted.
The first phase, there is a requirement for minimum number of participants, if it fails to collect enough sha3(s) within the time period, then RNG at this block height will fail.
- If a participant submits the sha3(s) and it is accepted by contract C, he must reveal the s in the second phase.
????- If the participant fails to reveal s in the second phase, then the m ETH sent in the first phase will be confiscated without providing a return.
????- If one or more s isn‘t revealed in the second phase, RNG at this block height will fail. Confiscated ETHs will be divided equally and send to other participants who revealed s at the second phase. The fees paid by other contracts will be refunded.
補充規則
為了確保RNG不能被操控,以及為了安全和效率,智能合約C有以下的補充規則:
- 在第一步中,如果有兩個或更多個的同樣的sha3(s)被提交上來,那麼只有第一個會被接受。
- 在第一步中,對於參與者有最低要求,如果在指定的時間區間內沒有收集到足夠多的sha3(s)的值,那麼RNG在這個區塊高度會失敗。
- 如果參與者提交了sha3(s),那麼他必須在第二步提交s
????- 如果參與者在第二步沒有提交s,那麼第一階段提供的m ETH會被沒收而且沒有獎勵。
????- 如果一個或者多個s沒有在第二步被提交,RNG在這個區塊高度會失敗。沒收的ETH會被分成同等分發送給提交了s的其他參與者。
其他申請隨機數的其他合約的費用會被退回。
Incentive
The RNG cycle is very short, and could be for example 20 cycles in one hour, if one cycle‘s profit is 0.001% , the monthly rate of return is up to 0.00001 20 24 30 = 0.144. Targeting to 14.4% monthly rate of return, and RNG has n participants on average, the running costs of contract is n 3 500 gasPrice + Ccost. (Ccost is gas consumed by contract internally, including computing and storage, etc. ) Assuming each random numbers has r time requests on average, the call price is p ETH, the income is r p. So each participant will get (rp - 1500n gasPrice - Ccost) / n from one time participation. The current gasPrice is 10 szabo, and estimate of contract consumption is 1500n gas, so estimate of net income is (rp / n - 0.03) ETH. Assuming each RNG has 10 participation, and the pledge is 1000ETH, the minimum required income is 0.4 ETH, which over 0.001% profit in this case. So if the RNG is requested only once, the service price is 0.4 ETH, and if it is requested 10 times, the price is just 0.04 ETH for each request.
區塊鏈教程以太坊源碼分析以太坊隨機數產生方式一