您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“以太坊Dapp開發(fā)方法是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“以太坊Dapp開發(fā)方法是什么”吧!
比特幣設(shè)計的初衷就是要避免依賴中心化的機構(gòu),沒有發(fā)行機構(gòu),也不可能操縱發(fā)行數(shù)量。既然沒有中心化的信用機構(gòu),在電子貨幣運行的過程中,也勢必需要一種機制來認可運行在區(qū)塊鏈上的行為(包括比特幣的運營,亦或是運行在區(qū)塊鏈上的其他業(yè)務),這種機制就是共識機制。在完全去中心化的區(qū)塊鏈上運行的比特幣,采用的是PoW(Proof of Work,工作量證明),該機制完美的解決了拜占庭將軍問題(存在異常的情況下仍能達成一致)。因為基礎(chǔ)網(wǎng)絡架構(gòu)為分布式,對單獨一個節(jié)點是無法控制或破壞整個網(wǎng)絡,掌握網(wǎng)內(nèi)51%的運算能力(非節(jié)點數(shù))才有可能操作交易,而這個代價大概要超過270億美元。
整個區(qū)塊鏈網(wǎng)絡中的數(shù)據(jù)是公開透明的,每個節(jié)點(參與者)都可自由加入該網(wǎng)絡中,下載到所有的數(shù)據(jù)。任意兩個節(jié)點間的數(shù)據(jù)交換無需互相信任,完全依靠區(qū)塊鏈中的交易歷史和數(shù)據(jù)的可追溯,以及共識機制來保證數(shù)據(jù)交換的正確且不可逆的執(zhí)行。
跟當前銀行網(wǎng)銀系統(tǒng)(特別是公司網(wǎng)銀系統(tǒng))的加密機制類似,區(qū)塊鏈的數(shù)據(jù)結(jié)構(gòu)和交易流程中大量的使用了公私鑰來加解密,保證數(shù)據(jù)的安全性?;谠摷夹g(shù)基礎(chǔ),甚至可以應用群組簽名來保證共有數(shù)據(jù)的安全性。任何事物既然有優(yōu)點,也同時會存在不足之處。根源于分布式網(wǎng)絡架構(gòu)和共識機制,在區(qū)塊鏈上運行的交易確認時間會比較長(比特幣的確認時間大概是15分鐘),交易并發(fā)數(shù)受限(比特幣的每秒交易數(shù)為7筆,而淘寶的每秒并發(fā)數(shù)能達到10萬左右),區(qū)塊的容量限制(當前為1M,區(qū)塊鏈的擴容一直在討論中),監(jiān)管難以介入,基于工作量證明的共識機制存在浪費系統(tǒng)資源和帶寬的問題。
區(qū)塊是一個包含在區(qū)塊鏈(公開賬簿)里的聚合了交易信息的容器。它由一個包含元數(shù)據(jù)的區(qū)塊頭和緊跟其后的構(gòu)成區(qū)塊主體的一長串交易組成。區(qū)塊頭是80字節(jié),而平均每個交易至少是250字節(jié),而且平均每個區(qū)塊至少包含超過500個交易。 區(qū)塊結(jié)構(gòu)如下圖
交易(Tx)詳情中的結(jié)構(gòu)如下圖
當一個節(jié)點從網(wǎng)絡接受到傳入的區(qū)塊時,它會驗證這些區(qū)塊,然后鏈接到現(xiàn)有的區(qū)塊鏈上,鏈接的形態(tài)如下圖:
由于每個區(qū)塊包含前一個區(qū)塊的HASH值,這就使得從創(chuàng)世塊到當前塊形成了一條塊鏈,每個區(qū)塊必定按時間順序跟隨在前一個區(qū)塊之后,因為如果不知道前一塊區(qū)塊的HASH值就沒法生成當前區(qū)塊。要改變一個已經(jīng)在塊鏈中存在一段時間的區(qū)塊,從計算上來說是不可行的,因為如果它被改變,它之后的每個區(qū)塊必須隨之改變。這些特性使得雙花比特幣非常困難,區(qū)塊鏈是比特幣的最大創(chuàng)新。
首先使用隨機數(shù)發(fā)生器生成一個 私鑰 。一般來說這是一個256bits的數(shù),擁有了這串數(shù)字就可以對相應 錢包地址 中的比特幣進行操作,所以必須被安全地保存起來。
私鑰經(jīng)過SECP256K1算法處理生成了公鑰。SECP256K1是一種橢圓曲線算法,通過一個已知私鑰時可以算得公鑰,而公鑰已知時卻無法反向計算出私鑰。這是保障比特幣安全的算法基礎(chǔ)。
同SHA256一樣,RIPEMD160也是一種Hash算法,由公鑰可以計算得到公鑰哈希,而反過來是行不通的。
將一個字節(jié)的地址版本號連接到公鑰哈希頭部(對于比特幣網(wǎng)絡的pubkey地址,這一字節(jié)為“0”),然后對其進行兩次SHA256運算,將結(jié)果的前4字節(jié)作為公鑰哈希的校驗值,連接在其尾部。
將上一步結(jié)果使用BASE58進行編碼(比特幣定制版本),就得到了錢包地址。
流程圖如下
比特幣錢包間的轉(zhuǎn)賬是通過交易(Transaction)實現(xiàn)的。交易數(shù)據(jù)是由轉(zhuǎn)出錢包私鑰的所有者生成,也就是說有了私鑰就可以花費該錢包的比特幣余額。生成交易的過程如下:
交易的原始數(shù)據(jù)包括“轉(zhuǎn)賬數(shù)額”和“轉(zhuǎn)入錢包地址”,但是僅有這些是不夠的,因為無法證明交易的生成者對“轉(zhuǎn)出錢包地址”余額有動用的權(quán)利。所以需要用私鑰對原始數(shù)據(jù)進行簽名。
生成“轉(zhuǎn)出錢包公鑰”,這一過程與生成錢包地址的第2步是一樣的。
將“轉(zhuǎn)出簽名”和“轉(zhuǎn)出公鑰”添加到原始交易數(shù)據(jù)中,生成了正式的交易數(shù)據(jù),這樣它就可以被廣播到比特幣網(wǎng)絡進行轉(zhuǎn)賬了。
簡單來說,以太坊是一種新的法律形式?,F(xiàn)行法律的本質(zhì)是一種合約。它是由(生活于某一社群的)人和他們的領(lǐng)導者之間所締結(jié)的,一種關(guān)于彼此該如何行動的共識。個體之間也存在著一些合約,這些合約可以理解為一種私法,相應的,這種私法僅對合約的參與者生效。
例如,你和一個人訂立合約,借給他一筆錢,但他最后毀約了,不打算還這筆錢。此時你多半會將對方告上法庭。在現(xiàn)實生活中,打官司這種事情常常混亂不堪并且充滿了不確定性。將對方告上法庭,也通常意味著你需要支付高昂的費用聘請律師,來幫你在法庭上針對法律條文展開辯論,而且這一過程一般都曠日持久。而且,即使你最終贏了官司,你依然可能會遇到問題(比如,對方拒不執(zhí)行法庭判決)。 令人欣慰的是,當初你和借款人把條款寫了下來,訂立了合約。但法律的制定者和合約的起草者們都必須面對一個不容忽視的挑戰(zhàn):那就是,理想情況下,法律或者合約的內(nèi)容應該是明確而沒有歧義的,但現(xiàn)行的法律和合約都是由語句構(gòu)成的,而語句,則是出了名的充滿歧義。 因此,一直以來,現(xiàn)行的法律體系都存在著兩個巨大的問題:首先,合約或法律是由充滿歧義的語句定義的,第二,強制執(zhí)行合約或法律的代價非常大。 而以太坊,通過數(shù)字貨幣和編程語言的結(jié)合,解決了現(xiàn)行法律體系的這兩大問題。 以太坊系統(tǒng)自身帶有一種叫做以太幣(Ether)的數(shù)字貨幣。以太幣和著名的數(shù)字貨幣比特幣(Bitcoin)有著非常多的相似之處。兩者均為數(shù)字儲值貨幣,且無法偽造,都以去中心化的方式運行來保證貨幣供應不被某一方所控制。兩者都可以像電子郵件一樣,作為貨幣自由地在全世界流通。而且,由于它們可以做到傳統(tǒng)貨幣做不到的事情,因此用戶對它們未來的價值充滿期待 。
另外: 1.詳情請閱讀以太坊白皮書 (中文, 英文)。 2.以太坊教程
公鑰加密系統(tǒng)。 Alice有一把公鑰和一把私鑰。她可以用她的私鑰創(chuàng)建數(shù)字簽名,而Bob可以用她的公鑰來驗證這個簽名確實是用Alice的私鑰創(chuàng)建的,也就是說,確實是Alice的簽名。當你創(chuàng)建一個以太坊或者比特幣錢包的時候,那長長的0xdf...5f地址實質(zhì)上是個公鑰,對應的私鑰保存某處。類似于Coinbase的在線錢包可以幫你保管私鑰,你也可以自己保管。如果你弄丟了存有資金的錢包的私鑰,你就等于永遠失去了那筆資金,因此你最好對私鑰做好備份。
點對點網(wǎng)絡。 就像BitTorrent, 以太坊分布式網(wǎng)絡中的所有節(jié)點都地位平等,沒有中心服務器。
區(qū)塊鏈。 區(qū)塊鏈就像是一個全球唯一的帳簿,或者說是數(shù)據(jù)庫,記錄了網(wǎng)絡中所有交易歷史。
以太坊虛擬機(EVM)。 它讓你能在以太坊上寫出更強大的程序(比特幣上也可以寫腳本程序)。它有時也用來指以太坊區(qū)塊鏈,負責執(zhí)行智能合約以及一切。
節(jié)點。 你可以運行節(jié)點,通過它讀寫以太坊區(qū)塊鏈,也即使用以太坊虛擬機。完全節(jié)點需要下載整個區(qū)塊鏈。輕節(jié)點仍在開發(fā)中。
礦工。 挖礦,也就是處理區(qū)塊鏈上的區(qū)塊的節(jié)點。這個網(wǎng)頁可以看到當前活躍的一部分以太坊礦工:stats.ethdev.com。
工作量證明。 礦工們總是在競爭解決一些數(shù)學問題。第一個解出答案的(算出下一個區(qū)塊)將獲得以太幣作為獎勵。然后所有節(jié)點都更新自己的區(qū)塊鏈。所有想要算出下一個區(qū)塊的礦工都有與其他節(jié)點保持同步,并且維護同一個區(qū)塊鏈的動力,因此整個網(wǎng)絡總是能達成共識。(注意:以太坊正計劃轉(zhuǎn)向沒有礦工的權(quán)益證明系統(tǒng)(POS),不過那不在本文討論范圍之內(nèi)。)
以太幣。 縮寫ETH。一種你可以購買和使用的真正的數(shù)字貨幣。這里是可以交易以太幣的其中一家交易所的走勢圖。在寫這篇文章的時候,1個以太幣價值65美分。
Gas. 在以太坊上執(zhí)行程序以及保存數(shù)據(jù)都要消耗一定量的以太幣,Gas是以太幣轉(zhuǎn)換而成。這個機制用來保證效率。
DApp. 以太坊社區(qū)把基于智能合約的應用稱為去中心化的應用程序(Decentralized App)。DApp的目標是(或者應該是)讓你的智能合約有一個友好的界面,外加一些額外的東西,例如IPFS(可以存儲和讀取數(shù)據(jù)的去中心化網(wǎng)絡,不是出自以太坊團隊但有類似的精神)。DApp可以跑在一臺能與以太坊節(jié)點交互的中心化服務器上,也可以跑在任意一個以太坊平等節(jié)點上。這里分享一個以太坊DApp教程,可以高效的學習如何開發(fā)一個DApp,很適合入門。
建議使用Mac OS環(huán)境,不然可能會出現(xiàn)各種坑。
安裝NodeJS,安裝Python。
安裝testrpc(測試環(huán)境中使用),安裝go-ethereum(真實環(huán)境中使用)。
安裝solc。
安裝truffle。
如果是windows的話建議用工具ethbox可以一鍵安裝以太坊開發(fā)環(huán)境的工具: ethbox
下面是官網(wǎng)上面的一段關(guān)于智能投票合約的示例代碼
contract Ballot { //一個選民的構(gòu)造體 struct Voter { uint weight; // 權(quán)重(即他可以投幾票) bool voted; //是否已經(jīng)投過票 address delegate; // 代表地址(他可以代表某個人進行投票) uint vote; // index of the voted proposal } // 投票的提案的構(gòu)造體 struct Proposal { bytes32 name; // 提案名稱 uint voteCount; //獲得的票數(shù) } address public chairperson;//會議主席 //地址 -選民 的map mapping(address => Voter) public voters; // 投票種類的動態(tài)數(shù)組 Proposal[] public proposals; ///構(gòu)造函數(shù) function Ballot(bytes32[] proposalNames) { chairperson = msg.sender;//初始化會議主席 voters[chairperson].weight = 1; //初始化所有的提案 for (uint i = 0; i < proposalNames.length; i++) { proposals.push(Proposal({ name: proposalNames[i], voteCount: 0 })); } } // 給予投票權(quán) function giveRightToVote(address voter) returns (bool b) { if (msg.sender != chairperson || voters[voter].voted) { //對于會議主席和已經(jīng)投過票的選民這里不處理 return false;; } voters[voter].weight = 1; return true; } /// 投票權(quán)轉(zhuǎn)移函數(shù) function delegate(address to) { // 投票權(quán)轉(zhuǎn)移的發(fā)起人 Voter sender = voters[msg.sender]; if (sender.voted) throw; //遞歸找到?jīng)]有轉(zhuǎn)移投票權(quán)的 選民 while ( voters[to].delegate != address(0) && voters[to].delegate != msg.sender ) { to = voters[to].delegate; } if (to == msg.sender) { throw; } //將發(fā)起人設(shè)置為已經(jīng)投過票的狀態(tài) sender.voted = true; //將代表設(shè)置為剛才遞歸獲取的選民 sender.delegate = to; Voter delegate = voters[to]; if (delegate.voted) { //如果代表已經(jīng)投過票就在他投票的提案的票數(shù)增加 proposals[delegate.vote].voteCount += sender.weight; } else { //將代表的的票數(shù)增加 delegate.weight += sender.weight; } } /// 投票函數(shù) function vote(uint proposal) { Voter sender = voters[msg.sender]; if (sender.voted) throw; sender.voted = true; sender.vote = proposal; //將投的提案票數(shù)增加 proposals[proposal].voteCount += sender.weight; } ///獲得票數(shù)最多的提案 function winningProposal() constant returns (uint winningProposal) { uint winningVoteCount = 0; for (uint p = 0; p < proposals.length; p++) { if (proposals[p].voteCount > winningVoteCount) { winningVoteCount = proposals[p].voteCount; winningProposal = p; } } } }
解讀
address. 地址類型。chairperson是會議主席的錢包地址。這個地址會在合約的構(gòu)造函數(shù)function Ballot()中被賦值。很多時候也稱呼這種地址為'owner'(所有人)。
public. 這個關(guān)鍵字表明變量可以被合約之外的對象使用。private修飾符則表示變量只能被本合約(或者衍生合約)內(nèi)的對象使用。如果你想要在測試中通過web3.js使用合約中的某個變量,記得把它聲明為public。
Mapping或數(shù)組。mapping(address => Voter)為選民錢包地址和選民構(gòu)造體的鍵值對。Proposal[] public proposals是一個提案構(gòu)造體的數(shù)組。
有特殊的變量和函數(shù)總是在全局命名空間存在,主要用于提供有關(guān)blockchain信息,例如msg,block,tx,其中msg.sender為發(fā)起人的地址。
solidity語言更深入的理解可以閱讀官方文檔。
啟動一個測試節(jié)點
geth --testnet --fast --cache=512 --genesis CustomGenesis.json console
這里的CustomGenesis.json是為了給測試的賬戶分配以太幣
{ "coinbase": "0x0000000000000000000000000000000000000000", "difficulty": "0x20000", "extraData": "", "gasLimit": "0x2fefd8", "nonce": "0x0000000000000042", "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "timestamp": "0x00", "alloc": { "0xe49c283bc6bf92c5833cc981b97679238dd3b5da": { "balance": "111111111000000000000000000000000000" }, "0xd8927c296b3ebe454a6409770a0c323ec4ed23ba": { "balance": "222222222000000000000000000000000000" } } }
solc下的內(nèi)容要替換成你的測試賬戶地址。具體geth的用法請查看官方文檔和源碼介紹。
使用solc編譯智能合約,獲得二進制代碼 例如以下代碼
contract test { function multiply(uint a) returns(uint d) { return a * 7; } }
在geth中輸入
source = "contract test { function multiply(uint a) returns(uint d) { return a * 7; } }"
clientContract = eth.compile.solidity(source).test
編譯返回的結(jié)果的JSON格式如下
其中,
code:編譯后的EVM字節(jié)碼
info:編譯器返回的metadata
abiDefination:Application Binary Interface定義。具體接口規(guī)則參見這里
compilerVersion:編譯此代碼的solidity編譯器版本
developerDoc:針對開發(fā)者的Natural Specification Format,類似于Doxygen
language:合約語言
languageVersion:合約語言版本
source:源代碼
userDoc:針對用戶的Ethereum的Natural Specification Format。
編譯器返回的JSON結(jié)構(gòu)反映了合約部署的兩種不同的路徑。info信息真實的存在于區(qū)中心化的云中,作為metadata信息來公開驗證Blockchain中合約代碼的實現(xiàn)。而code信息通過創(chuàng)建交易的方式部署到區(qū)塊鏈中。
使用solc編譯智能合約,獲得二進制代碼 部署合約前,確保你有一個解鎖的賬戶并且賬戶中有余額,因為部署合約得過程中會消耗以太幣。輸入web3.fromWei(eth.getBalance(eth.accounts[0]),"ether")可以查看賬戶余額。 解鎖一個賬戶
personal.unlockAccount(eth.accounts[0])
獲得賬戶
primaryAddress = eth.accounts[0]
定義一個abi (abi是個js的數(shù)組,否則不成功)
abi = [{ constant: false, inputs: [{ name: 'a', type: 'uint256' } ]}]
創(chuàng)建智能合約
MyContract = eth.contract(abi)
發(fā)送交易部署合約
contract = MyContract.new({from: primaryAddress, data:"0x6060604052602a8060106000396000f3606060405260e060020a6000350463c6888fa18114601a575b005b6007600435026060908152602090f3"})
如果交易被pending,如圖說明你的miner沒有在挖礦
啟動一個礦工 miner.setEtherbase(eth.primaryAddress) //設(shè)定開采賬戶 miner.start(8)
eth.getBlock("pending", true).transactions 這時候發(fā)現(xiàn)交易已經(jīng)在區(qū)塊中
不過會發(fā)現(xiàn),交易還是pending,這是因為該交易區(qū)塊沒有人協(xié)助進行運算驗證,這時候只需要再啟動一個礦工就行了 miner.start(8)
與合約進行交互
Multiply7 = eth.contract(clientContract.info.abiDefinition); var myMultiply7 = Multiply7.at(contract.address); myMultiply7.multiply.call(3) 或 myMultiply7.multiply.sendTransaction(3, {from: contract.address})
使用truffle部署智能合約的步驟:
truffle init (在新目錄中) => 創(chuàng)建truffle項目目錄結(jié)構(gòu),
編寫合約代碼,保存到contracts/YourContractName.sol文件。 例如Ballot .sol,此時要找到migrations文件夾,在deploy_contracts.js文件中添加deployer.deploy(Ballot);
truffile compile 編譯合約代碼。
啟動以太坊節(jié)點(例如在另一個終端里面運行testrpc)。
truffle migrate(在truffle項目目錄中)。
在test文件夾中新建ballot.js文件
contract('Ballot',function(accounts)){ //accounts是所以賬戶得數(shù)值 it("獲取投票權(quán)",function(){ var meta = Ballot.deployed(); return meta.giveRightToVote(accounts[1]).then(function(b){ assert.equal(Boolean(b),true,"獲取投票權(quán)失敗"); }); }); }
在項目根目錄下運行truffle test,你應該看到測試通過,如果使用自己構(gòu)造的ballot對象,可以這樣寫:
contract('Ballot',function(accounts)){ //accounts是所以賬戶得數(shù)值 it("獲取投票權(quán)",function(){ var proposals = []; proposals.push("proposal0"); Ballot.new(proposals).then(function(meta){ return meta.giveRightToVote(accounts[1]).then(function(b){ assert.equal(Boolean(b),true,"獲取投票權(quán)失敗"); }); }); }); }
合約中發(fā)送以太幣。 this是合約實例的地址,以變接下來檢查這個地址的余額(或者直接使用this.balance)
當你通過web3.js調(diào)用交易函數(shù)時(使用web3.eth.sendTransaction),交易并不會立即執(zhí)行。事實上交易會被提交到礦工網(wǎng)絡中,交易代碼直到其中一位礦工產(chǎn)生一個新區(qū)塊把交易記錄進區(qū)塊鏈之后才執(zhí)行。因此你必須等交易進入?yún)^(qū)塊鏈并且同步回本地節(jié)點之后才能驗證交易執(zhí)行的結(jié)果。用testrpc的時候可能看上去是實時的,因為測試環(huán)境很快,但是正式網(wǎng)絡會比較慢。
Gas. (譯注:以太坊上的燃料,因為代碼的執(zhí)行必須消耗Gas。直譯為汽油比較突兀,故保留原文做專有名詞。)直到現(xiàn)在我們都沒有涉及Gas的概念,因為在使用testrpc時通常不需要顯式的設(shè)置。當你轉(zhuǎn)向geth和正式網(wǎng)絡時會需要。在交易函數(shù)調(diào)用中可以在{ from: _, value: _, gas: _ } 對象內(nèi)設(shè)置Gas參數(shù)。Web3.js提供了web3.eth.gasPrice調(diào)用來獲取當前Gas的價格,Solidity編譯器也提供了一個參數(shù)讓你可以從命令行獲取合約的Gas開銷概要:solc --gas YouContract.sol.
在app目錄中,可以編寫自己的html和js文件,js與智能合約的交互與單元測試基本一致,例如一個界面上有一個輸入框和一個按鈕,獲得選民的投票權(quán)。
<!DOCTYPE html> <html> <head> <title>Ballot App</title> <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'> <link href="./app.css" rel='stylesheet' type='text/css'> <script src="./app.js"></script> </head> <body> <h2>Ballot</h2> <h3>Example Truffle Dapp</h3> <br> <h2>Send</h2> <br><label for="amount">Account:</label><input type="text" id="account" placeholder="e.g., 0x453468394hdfg84858345348"></input> <br><br><button id="getRightVote" onclick="getRight()">Get Right Vote</button> <br><br> <span id="status"></span> </body> </html>
app.js中的代碼為
function getRight() { var account = document.getElementById("account").value; var meta = Ballot.deployed(); meta.giveRightToVote(account).then(function(b){ if(Boolean(b)){ setStatus("Get Right Vote Success"); }else{ setStatus("Get Right Vote Error"); } }).catch(function(e){ setStatus("Get Right Vote Error"); console.log(e); }); };
到此,相信大家對“以太坊Dapp開發(fā)方法是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學習!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。