$ nvm install --lts
開發工具,框架和庫
框架
框架可使以太坊智能合約開發變得輕鬆。自己做所有事情,你可以更好地理解所有事物如何結合在一起,但這是一項繁瑣而重複的工作。下面列出的框架可以自動執行某些任務並使開發變得輕而易舉。
Truffle
Truffle Boxes; http://Truffleframework.com/boxes/
npm package repository; https://www.npmjs.com/package/Truffle
安裝 Truffle 框架
Truffle 框架由多個 NodeJS包組成。在我們安裝Truffle之前,我們需要安裝NodeJS和Node Package Manager(npm)的最新版。
推薦的安裝 NodeJS 和 npm 的方法是使用node版本管理器(NVM)nvm。一旦我們安裝了nvm,它將為我們處理所有依賴和更新。我們將按照以下網址中的說明進行操作:
一旦在你的作業系統上安裝了nvm,安裝NodeJS就很簡單了。我們使用--lts標誌告訴nvm我們想要最新的“長期支持(LTS)”版本NodeJS
確認你已安裝 node 和 npm:
$ node -v v8.9.4 $ npm -v 5.6.0
創建一個包含DApp支持的Node.js版本的隱藏檔案.nvmrc,這樣開發人員只需要在項目目錄的根目錄下運行nvm install
,它就會自動安裝並切換到使用該版本。
$ node -v > .nvmrc $ nvm install
看起來不錯。現在安裝Truffle:
$ npm -g install Truffle + Truffle@4.0.6 installed 1 package in 37.508s
集成預編譯的 Truffle 項目 (Truffle Box)
如果我們想要使用或創建一個建立在預先構建的樣板上的DApp,那麼在Truffle Boxes鏈接中,我們可以選擇一個現有的Truffle項目,然後運行以下命令來下載並提取它:
$ Truffle unbox <BOX_NAME>
創建 Truffle 項目目錄
對於我們將使用Truffle的每個項目,我們創建一個項目目錄並在該目錄中初始化Truffle。Truffle將在我們的項目目錄中創建必要的目錄結構。通常,我們為項目目錄指定一個描述我們項目的名稱。對於這個例子,我們將使用Truffle從 [simple_contract_example] 部署我們的Faucet合約,因此我們將命名項目檔案夾Faucet。
$ mkdir Faucet $ cd Faucet Faucet $
一旦進入 Faucet 目錄,我們初始化 Truffle:
Faucet $ Truffle init
Truffle創建了一個目錄結構和一些預設檔案:
Faucet ├── contracts │ └── Migrations.sol ├── migrations │ └── 1_initial_migration.js ├── test ├── Truffle-config.js └── Truffle.js
除了Truffle本身之外,我們還將使用一些JavaScript(nodeJS)支持包。我們可以用npm安裝這些。我們初始化npm目錄結構並接受npm建議的預設值:
$ npm init package name: (faucet) version: (1.0.0) description: entry point: (Truffle-config.js) test command: git repository: keywords: author: license: (ISC) About to write to Faucet/package.json: { "name": "faucet", "version": "1.0.0", "description": "", "main": "Truffle-config.js", "directories": { "test": "test" }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" } Is this ok? (yes)
現在,我們可以安裝我們用來使Truffle變得更容易的依賴關係:
$ npm install dotenv Truffle-wallet-provider ethereumjs-wallet
你現在有一個帶有數千個檔案的node_modules目錄。
在將DApp部署到雲生產或持續集成環境之前,指定 engines 欄位非常重要,以便你的Dapp使用正確的Node.js版本進行構建,並且會安裝相關的依賴關係。
Package.json“engines”欄位配置鏈接; https://docs.npmjs.com/files/package.json#engines
配置 Truffle
Truffle 創建一些空的配置檔案,Truffle.js和Truffle-config.js。在Windows系統上,當你嘗試運行命令Truffle,Windows嘗試運行Truffle.js時,+ Truffle.js+名稱可能會導致衝突。為了避免這種情況,我們將刪除Truffle.js並使用Truffle-config.js來支持Windows用戶,他們的確已經受夠了。
$ rm Truffle.js
現在我們編輯 Truffle-config.js 並用下面的內容替換:
module.exports = {
networks: {
localnode: { // Whatever network our local node connects to
network_id: "*", // Match any network id
host: "localhost",
port: 8545,
}
}
};
以上配置是一個很好的起點。它設置了一個預設的以太坊網路(名為localnode),該網路假定你正在運行以太坊客戶端(如Parity),既可以作為完整節點,也可以作為輕客戶端。該配置將指示Truffle與連接埠8545上的本地節點通過RPC進行通信。Truffle將使用本地節點連接的任何以太網(如Ethereum主網路)或測試網路(如Ropsten)。本地節點也將提供錢包功能。
在下面的章節中,我們將配置其他網路供Truffle使用,比如ganache test-RPC區塊鏈和託管網路提供商Infura。隨著我們添加更多網路,配置檔案將變得更加複雜,但它也將為我們的測試和開發工作流程提供更多選擇。
使用Truffle部署合約
我們現在有一個針對我們的 Faucet 項目的基本工作目錄,並且我們已經配置了Truffle和它的依賴關係。合約在我們項目的contracts +子目錄中。該目錄已經包含一個“helper”合約,+Migrations.sol管理合約升級。我們將在後面的章節中研究 Migrations.sol 的使用。
讓我們將 Faucet.sol 合約([solidity_faucet_example])複製到contracts子目錄中,以便項目目錄如下所示:
Faucet ├── contracts │ ├── Faucet.sol │ └── Migrations.sol ...
我們現在可以讓Truffle編譯我們的合約:
$ Truffle compile Compiling ./contracts/Faucet.sol... Compiling ./contracts/Migrations.sol... Writing artifacts to ./build/contracts
Truffle migrations - 理解部署腳本
Truffle提供了一個名為migration的部署系統。如果你曾在其他框架中工作過,你可能會看到類似的東西:Ruby on Rails,Python Django和許多其他語言和框架都有migrate命令。
在所有這些框架中,migration的目的是處理不同版本軟體之間數據模式的變化。以太坊migration的目的略有不同。因為以太坊合約是不可變的,而且要消耗gas部署,所以Truffle提供了一個migration機制來跟蹤哪些合約(以及哪些版本)已經部署。在一個擁有數十個合約和複雜依賴關係的複雜項目中,你不希望為了重新部署尚未更改的合約而支付gas。你也不想手動跟蹤哪些合約的哪些版本已經部署了。Trufflemigration機制通過部署智能合約Migrations.sol完成所有這些工作,然後跟蹤所有其他合約部署。
我們只有一份合約,Faucet.sol,這至少意味著migration系統是大材小用的。不幸的是,我們必須使用它。但是,通過學習如何將它用於一個合約,我們可以開始練習一些良好的開發工作習慣。隨著事情變得更加複雜,這項努力將會得到回報。
Truffle的migrations目錄是找到遷移腳本的地方。現在,只有一個腳本 1_initial_migration.js,它會部署 Migrations.sol 合約本身:
[[1_initial_migration]] .1_initial_migration.js - the migration script for Migrations.sol
include::code/truffle/Faucet/migrations/1_initial_migration.js
var Migrations = artifacts.require("./Migrations.sol");
module.exports = function(deployer) {
deployer.deploy(Migrations);
};
我們需要第二個migration腳本來部署 Faucet.sol。我們稱之為2_deploy_contracts.js。它非常簡單,就像1_initial_migration.js一樣,只需稍作修改即可。實際上,你可以複製+ 1_initial_migration.js+的內容,並簡單地將Migrations的所有實例替換為Faucet:
[[2_deploy_contracts]] .2_deploy_contracts.js - the migration script for Faucet.sol
include::code/truffle/Faucet/migrations/2_deploy_contracts.js
var Faucet = artifacts.require("./Faucet.sol");
module.exports = function(deployer) {
deployer.deploy(Faucet);
};
腳本初始化變數Faucet,將Faucet.sol Solidity源程式碼標識為定義Faucet的工件。然後,它調用部署功能來部署此合約。
我們都準備好了。我們使用 truffle migrate 來部署合約。我們必須使用--network參數指定在哪個網路上部署合約。我們只在配置檔案中指定了一個網路,我們將其命名為localnode。確保你的本地以太坊客戶端正在運行,然後輸入:
Faucet $ Truffle migrate --network localnode
因為我們使用本地節點連接到以太坊網路並管理我們的錢包,所以我們必須授權Truffle創建的交易。我正在運行parity連接到Ropsten測試區塊鏈,所以在Trufflemigration期間,我會在parity的Web控制台上看到一個彈出視窗:
你將看到四筆交易,總計。一個部署Migrations,一個用於將部署計數器更新為1,一個用於部署Faucet,另一個用於將部署計數器更新為2。
Truffle將顯示migration完成情況,顯示每個交易並顯示合約地址:
$ Truffle migrate --network localnode Using network 'localnode'. Running migration: 1_initial_migration.js Deploying Migrations... ... 0xfa090db179d023d2abae543b4a21a1479e70ca7d35a469a5d1a98bfc6bd80fe8 Migrations: 0x8861c27715550bed8362c0345add158489df6db0 Saving successful migration to network... ... 0x985c4a32716826ddbe4eae284104bef8bc69e959899f62246a1b27c9dfcd6c03 Saving artifacts... Running migration: 2_deploy_contracts.js Deploying Faucet... ... 0xecdbeef77f0558edc689440e34b7bba0a3ba7a45e4b680b071b47c30a930e9d6 Faucet: 0xd01cd8e7bd29e4bff8c1693f59eee46137a9f300 Saving successful migration to network... ... 0x11f376bd7307edddfd40dc4a14c3f7cb84b6c921ac2465602060b67d08f9fd8a Saving artifacts...
使用Truffle控制台
Truffle提供了一個JavaScript控制台,我們可以使用這個控制台與Ethereum網路(通過本地節點)進行交互,與已部署的合約進行交互,並與錢包提供商進行交互。在我們當前的配置(localnode)中,節點和錢包提供商是我們的本地parity客戶端。
讓我們開始Truffle控制台並嘗試一些命令:
$ Truffle console --network localnode Truffle(localnode)>
Truffle提示一個提示符,顯示所選的網路配置(localnode)。記住並瞭解我們正在使用哪個網路很重要。你不希望在Ethereum主網路上意外部署測試合約或進行交易。這可能是一個昂貴的錯誤!
Truffle控制台提供了自動補全功能,使我們可以輕鬆探索環境。如果我們在部分完成的命令後按Tab,Truffle將為我們完成命令。如果有多個命令與我們的輸入相匹配,按Tab兩次將顯示所有可能的完成。事實上,如果我們在空提示符下按兩次Tab,Truffle將列出所有命令:
Truffle(localnode)> Array Boolean Date Error EvalError Function Infinity JSON Math NaN Number Object RangeError ReferenceError RegExp String SyntaxError TypeError URIError decodeURI decodeURIComponent encodeURI encodeURIComponent eval isFinite isNaN parseFloat parseInt undefined ArrayBuffer Buffer DataView Faucet Float32Array Float64Array GLOBAL Int16Array Int32Array Int8Array Intl Map Migrations Promise Proxy Reflect Set StateManager Symbol Uint16Array Uint32Array Uint8Array Uint8ClampedArray WeakMap WeakSet WebAssembly XMLHttpRequest _ assert async_hooks buffer child_process clearImmediate clearInterval clearTimeout cluster console crypto dgram dns domain escape events fs global http http2 https module net os path perf_hooks process punycode querystring readline repl require root setImmediate setInterval setTimeout stream string_decoder tls tty unescape url util v8 vm web3 zlib __defineGetter__ __defineSetter__ __lookupGetter__ __lookupSetter__ __proto__ constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf
絕大多數錢包和節點相關功能由web3物件提供,該物件是 web3.js庫的一個實例。web3物件將RPC接口抽象為我們的parity節點。你還會注意到兩個熟悉名稱的物件:Migrations 和 Faucet。這些代表我們剛剛部署的合約。我們將使用Truffle控制台與合約進行交互。首先,讓我們通過 web3 物件檢查我們的錢包:
Truffle(localnode)> web3.eth.accounts [ '0x9e713963a92c02317a681b9bb3065a8249de124f', '0xdb5dc1a13e3a55cf3b4587cd8d1e5fdeb6738145' ]
我們的parity客戶端有兩個錢包,Ropsten有一些測試ether。web3.eth.accounts 屬性包含所有帳戶的列表。我們可以使用 getBalance 函數檢查第一個帳戶的餘額:
Truffle(localnode)> web3.eth.getBalance(web3.eth.accounts[0]).toNumber() 191198572800000000 Truffle(localnode)>
web3.js 是一個大型JavaScript庫,通過提供者(如本地客戶端)為以太坊系統提供全面的界面。我們將在[web3js]中更詳細地研究web3.js。現在讓我們嘗試與我們的合約進行交互:
Truffle(localnode)> Faucet.address '0xd01cd8e7bd29e4bff8c1693f59eee46137a9f300' Truffle(localnode)> web3.eth.getBalance(Faucet.address).toNumber() 0 Truffle(localnode)>
接下來,我們將使用 sendTransaction 發送一些測試ether,為 Faucet 提供資金。請注意使用web3.toWei為我們轉換ether單位。在沒有出錯的情況下輸入十八個零既困難又危險,因此使用單位轉換器來獲取值總是更好。以下是我們發送交易的方式:
Truffle(localnode)> web3.eth.sendTransaction({from:web3.eth.accounts[0], to:Faucet.address, value:web3.toWei(0.5, 'ether')}); '0xf134c75b985dc0e0c27c2f0412251e0860eb530a5055e660f21e7483ab336808'
切換到parity的Web控制台,你將看到一個彈出視窗,要求你確認該交易。等一下,一旦交易開始,你將能夠看到我們的Faucet合約的餘額:
Truffle(localnode)> web3.eth.getBalance(Faucet.address).toNumber() 500000000000000000
我們調用withdraw函數,從Faucet中取出一些測試ether:
Truffle(localnode)> Faucet.deployed().then(instance => {instance.withdraw(web3.toWei(0.1, 'ether'))}).then(console.log)
同樣,你需要批准parity Web控制台中的交易。Faucet的餘額已經下降,我們的測試錢包已經收到0.1 ether:
Truffle(localnode)> web3.eth.getBalance(Faucet.address).toNumber() 400000000000000000
Truffle(localnode)> Faucet.deployed().then(instance => {instance.withdraw(web3.toWei(1, 'ether'))})
StatusError: Transaction: 0xe147ae9e3610334ada8d863c9028c12bd0501be2d0cfd05865c18612b92d3f9c exited with an error (status 0).
OpenZeppelin
OpenZeppelin 是Solidity語言的一個可重複使用且安全的智能合約的開放框架。
它由社區驅動,由https://zeppelin.solutions/[Zeppelin]團隊領導,擁有超過一百名外部貢獻者。該框架的主要重點是安全,通過應用行業標準合約安全模式和最佳實踐,利用zeppelin開發者從https://blog.zeppelin.solutions/tagged/security[auditing]中獲得的所有經驗大量的合約,並通過社區的持續測試和審計,使用該框架作為其實際應用的基礎。
OpenZeppelin框架是以太坊智能合約使用最廣泛的解決方案。這是由於社區討論每個提議的解決方案並從這些解決方案的實施和整合中學習,這將變成一個不斷增長的反饋迴圈,改進現有合約並找到將它們結合在一個清晰安全的體系結構中的新可能性。它不斷增加新的可重用合約來解決越來越複雜的挑戰,或在以太坊區塊鏈上探索激動人心的新可能性。如前所述,該框架目前擁有豐富的合約庫,從ERC20和ERC721 token的實現,到眾多的crowdsale模型,到簡單的行為,例如Ownable
,Pausable
或LimitBalance
。
在某些情況下,此儲存庫中的合約甚至作為de facto標準實現。
該框架擁有MIT許可證,並且所有合約都採用模塊化方法進行設計,以確保易用性和擴展性。這些都是乾淨而基本的構建塊,可以在你的下一個以太坊項目中使用。讓我們設置框架,並使用OpenZeppelin合約構建一個簡單的crowdsale,作為使用它的簡單例子。這個例子還強調了重用安全組件的重要性,而不是自己編寫安全組件,並給出了以太坊平臺及其社區成為可能的想法的一個小樣本。
首先,我們需要將npm中的openzepelin-solidity庫安裝到我們的工作區中。截至撰寫本文時的最新版本是v1.9.0
,所以我們將使用該版本。
mkdir sample-crowdsale cd sample-crowdsale npm install openzeppelin-solidity@1.9.0 mkdir contracts
對於crowdsale而言,我們需要定義一個token,我們會給予投資者以換取其ether。在撰寫本文時,OpenZeppelin包含了遵循ERC20,ERC721和ERC827標準的多個基本token合約,具有不同的發行,限制,兌現,生命週期等特徵。
讓我們製作一個ERC20 token,這意味著初始供應從0開始,token所有者(在我們的例子中,是crowdsale合約)可以創建新的 token並分配給投資者。為此,使用以下內容創建contracts/SampleToken.sol
檔案:
include::code/OpenZeppelin/contracts/SampleToken.sol pragma solidity 0.4.23; import 'openzeppelin-solidity/contracts/token/ERC20/MintableToken.sol'; contract SampleToken is MintableToken { string public name = "SAMPLE TOKEN"; string public symbol = "SAM"; uint8 public decimals = 18; }
OpenZeppelin已經提供了一個MintableToken合約,我們可以用它作為token的基礎,所以我們只定義特定於我們案例的細節。你可以相信社區已經付出很大的努力來確保合約的正確性,但最好自己核實一下。看看https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v1.9.0/contracts/token/ERC20/MintableToken.sol[MintableToken],https://github.com/OpenZeppelin的源程式碼/openzeppelin-solidity/blob/v1.9.0/contracts/token/ERC20/StandardToken.sol[StandardToken]和https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v1.9.0/contracts/ownership/Ownable.sol[Ownable]瞭解新token的實現細節及其支持的功能。另外,看看https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/test/token/ERC20/MintableToken.test.js[automated tests]以確保所有可能的場景都已經被覆蓋,並且程式碼是安全的。
接下來,我們來製作Crowdsale(ICO)合約。就像 token一樣,OpenZeppelin已經提供了各種各樣的Crowdsale。目前,你將找到涉及分配、發行,價格和驗證的方案的合約。因此,假設你想為Crowdsale設定一個目標,並且如果在銷售完成時沒有達到目標,你想要退還所有投資者。為此,你可以使用https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v1.9.0/contracts/crowdsale/distribution/RefundableCrowdsale.sol[RefundableCrowdsale]合約。也許你想定義一個價格上漲的眾籌來激勵早期買家:https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v1.9.0/contracts/crowdsale/price/IncreasingPriceCrowdsale.sol[IncreasingPriceCrowdsale],或者設定一個截止時間:https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v1.9.0/contracts/crowdsale/validation/TimedCrowdsale.sol[TimedCrowdsale],或者設定購買者白名單:https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v1.9.0/contracts/crowdsale/validation/WhitelistedCrowdsale.sol[WhitelistedCrowdsale]。
正如我們之前所說的,OpenZeppelin合約是基本的構建塊。這些crowdsale合約被設計為可組合的,只需閱讀 Crowdsale合約的源程式碼即可瞭解關於如何擴展它的指導。對於我們token的crowdsale,我們需要在crowdsale合約收到ether時才發行token,所以讓我們使用https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v1.9.0/contracts/crowdsale/emission/MintedCrowdsale.sol[MintedCrowdsale] 作為基礎。為了讓它更有趣,讓我們把它做成 PostDeliveryCrowdsale, token只能在眾籌結束後贖回。將以下內容寫入contracts/SampleCrowdsale.sol
:
include::code/OpenZeppelin/contracts/SampleCrowdsale.sol pragma solidity 0.4.23; import './SampleToken.sol'; import 'openzeppelin-solidity/contracts/crowdsale/emission/MintedCrowdsale.sol'; import 'openzeppelin-solidity/contracts/crowdsale/distribution/PostDeliveryCrowdsale.sol'; contract SampleCrowdsale is PostDeliveryCrowdsale, MintedCrowdsale { constructor( uint256 _openingTime, uint256 _closingTime uint256 _rate, address _wallet, MintableToken _token ) public Crowdsale(_rate, _wallet, _token) PostDeliveryCrowdsale(_openingTime, _closingTime) { } }
同樣,我們幾乎不需要編寫任何程式碼,只是為了重用OpenZeppelin社區為我們提供的已經經過測試的程式碼。但是,需要注意的是,這種情況與我們的SampleToken
合約不同。如果你訪問https://github.com/OpenZeppelin/openzeppelin-solidity/tree/v1.9.0/test/crowdsale[Crowdsale自動化測試],你會看到它們被隔離測試。當你將不同的程式碼單元集成到一個更大的組件中時,單獨測試所有的單元是不夠的,因為它們之間的交互可能會導致你沒有預料到的行為。特別是,你會看到在這裡我們介紹了多重繼承,如果他們不瞭解Solidity編譯器的實現細節,這可能會讓開發人員感到意外。我們的SampleCrowdsale
非常簡單,並且能夠像我們所期望的那樣工作,因為框架旨在使這些案例變得簡單明瞭;但不要因為這個框架引入的簡單性,放鬆你的安全性。每當你集成部分OpenZeppelin框架以構建更復雜的解決方案時,你必須全面測試解決方案的每個方面,以確保單元的所有交互按照你的意圖運行。
最後,在我們對我們的解決方案感到滿意並且我們已經徹底測試之後,我們需要部署它。OpenZeppelin與Truffle很好地集成在一起,所以我們可以按照上面的Truffle部分所述編寫一個migration檔案。在 migrations/2_deploy_contracts.js 中寫入以下內容:
include::code/OpenZeppelin/migrations/2_deploy_contracts.js const SampleCrowdsale = artifacts.require('./SampleCrowdsale.sol'); const SampleToken = artifacts.require('./SampleToken.sol'); module.exports = function(deployer, network, accounts) { const openingTime = web3.eth.getBlock('latest').timestamp + 2; // two secs in the future const closingTime = openingTime + 86400 * 20; // 20 days const rate = new web3.BigNumber(1000); const wallet = accounts[1]; return deployer .then(() => { return deployer.deploy(SampleToken); }) .then(() => { return deployer.deploy( SampleCrowdsale, openingTime, closingTime, rate, wallet, SampleToken.address ); }); };
這只是OpenZeppelin框架中一些合約的簡要概述。還有更多,社區總是提出新的想法,實施新的策略以使它們更安全,更簡單,更清晰,並儘早發現漏洞以防止主要網路合約中的漏洞。歡迎你加入社區進行學習和貢獻。
Website link; https://openzeppelin.org/
zeppelin_os
zeppelin_os 是一款開源的分佈式工具和服務平臺,位於EVM之上,安全地開發和管理智能合約應用程式。
與OpenZeppelin的程式碼每次都需要重新部署每個應用程式不同,zeppelin_os的程式碼處於鏈上。需要特定功能的應用程式(例如ERC20 token)不僅不需要重新設計和重新審計其實施(OpenZeppelin解決了這些問題),而且甚至不需要部署它。使用zeppelin_os,應用程式可直接與 鏈上的token實現進行交互,這與桌面應用程式與其底層作業系統的組件進行交互的方式大致相同。
利用OpenZeppelin的應用程式通過重用庫的組織和同行評審合約避免了“重新發明輪子”。然而,每當應用程式使用ERC20 token實現時,同一個ERC20 Bytecode 會一次又一次地部署到區塊鏈中。這種 Bytecode 在網路中無數次重複存在。現在,使用zeppelin_os的應用程式可以避免這種不必要的重複。他們並沒有部署自己的ERC20實施,而是鏈接到定義了社區接受的最新ERC20實現的合約。這種單一的中央實現僅部署在區塊鏈中,與Solidity的庫非常相似,但卻相當複雜。
與Solidity的庫不同,zeppelin_os提供的實現可以像常規合約一樣對待,即它們具有儲存空間。而且,它們是可升級的。如果在其中一個OS的官方實現中發現了一個漏洞,它可以簡單地與升級的漏洞交換。對於ERC20 token,對其實施的升級會立即波及到所有使用它的應用程式。作業系統不僅為其所有實現提供可升級性,還為用戶自己的合約提供升級能力,甚至為其自己的程式碼庫提供升級能力!開發人員決定應用程式何時以及如何實施升級,甚至決定要遵守哪種實施方案。
zeppelin_os的核心是一個非常聰明的合約,被稱為“代理(proxy)”。代理是一種能夠包裝任何其他合約,暴露其接口而無需手動實現setter和getter的合約,並且可以在不丟失狀態的情況下進行升級。在Solidity術語中,它可以被看作是一個正常的合約,其業務邏輯包含在一個庫中,隨時可以由一個新庫來交換,而不會丟失其狀態。代理鏈接到其實現的方式是完全自動的,並且封裝給開發人員。實際上,任何合約都可以升級,程式碼幾乎不變。關於zeppelin_os的代理機制的更多資訊可以在Zeppelin的博客中找到:https://blog.zeppelinos.org/[upgradeability-using-unstructured-storage],
作業系統將其實現封裝在可使用ZepTokens擔保(vouched)的軟體包或“發行版”中。因此,可以針對某個版本押注ZepTokens,將其標識為社區可接受的實現集。任何人都可以提交新的發行版,由社區審查並最終被接受為官方的新版本。作為獎勵,發行版的開發者在它每次被押注時都會收到token。作為一名Dapp開發人員,擔保(vouching)提供了一種可測量的方式來確定給定發行版獲得的支持,以及可信度。
使用Zeppelin_os開發應用程式與使用NPM開發Javascript應用程式類似。AppManager處理應用程式的每個版本的應用程式包。包只是一個合約目錄,每個合約都可以有一個或多個可升級的代理。AppManager不僅為特定於應用程式的合約提供代理,而且還以標準庫的形式為Zeppelin_os實現提供代理。要查看這方面的完整範例,請訪問:https://github.com/zeppelinos/zos-lib/tree/master/[examples/complex]。
//// TODO: the example provided above is still a WIP - link to a tutorial once it’s finished
雖然目前正在開發中,但zeppelin_os旨在提供一系列附加功能,例如開發人員工具,自動執行合約中後臺操作的調度程式,開發獎勵,促進應用程式之間進行通信和交換價值的市場等等。所有這些都在zeppelin_os的https://zeppelinos.org/zeppelin_os_[whitepaper].pdf中描述。
Github link; https://github.com/zeppelinos Website link; https://zeppelinos.org Blog: https://blog.zeppelinos.org Github: https://github.com/zeppelinos
實用程式
ethereumJS helpeth: 命令行實用程式
helpeth是一個命令行工具,使開發人員更容易的操作密鑰和交易。
它是基於JavaScript的庫和工具集合ethereumjs的一部分。
Usage: helpeth [command] Commands: signMessage <message> Sign a message verifySig <hash> <sig> Verify signature verifySigParams <hash> <r> <s> <v> Verify signature parameters createTx <nonce> <to> <value> <data> Sign a transaction <gasLimit> <gasPrice> assembleTx <nonce> <to> <value> <data> Assemble a transaction from its <gasLimit> <gasPrice> <v> <r> <s> components parseTx <tx> Parse raw transaction keyGenerate [format] [icapdirect] Generate new key keyConvert Convert a key to V3 keystore format keyDetails Print key details bip32Details <path> Print key details for a given path addressDetails <address> Print details about an address unitConvert <value> <from> <to> Convert between Ethereum units Options: -p, --private Private key as a hex string [string] --password Password for the private key [string] --password-prompt Prompt for the private key password [boolean] -k, --keyfile Encoded key file [string] --show-private Show private key details [boolean] --mnemonic Mnemonic for HD key derivation [string] --version Show version number [boolean] --help Show help [boolean]
dapp.tools
安裝:
$ curl https://nixos.org/nix/install | sh $ nix-channel --add https://nix.dapphub.com/pkgs/dapphub $ nix-channel --update $ nix-env -iA dapphub.{dapp,seth,hevm,evmdis}
SputnikVM
SputnikVM是一個獨立的可插拔的用於不同的基於以太坊的區塊鏈的虛擬機。它是用Rust編寫的,可以用作二進制,貨物箱,共享庫,或者通過FFI,Protobuf和JSON接口集成。它有一個單獨的用於測試目的的二進制sputnikvm-dev,它模擬大部分JSON RPC API和區塊挖掘。
Github link; https://github.com/etcdevteam/sputnikvm
Libraries
web3.js
web3.js是以太坊兼容的JS API,用於通過以太坊基金會開發的JSON RPC與客戶進行通信。
Github link; https://github.com/ethereum/web3.js
npm package repository link; https://www.npmjs.com/package/web3
Documentation link for web3.js API 0.2x.x; https://github.com/ethereum/wiki/wiki/JavaScript-API
Documentation link for web3.js API 1.0.0-beta.xx; https://web3js.readthedocs.io/en/1.0/web3.html
web3.py
web3.py 是一個用於與以太坊區塊鏈進行交互的Python庫。它現在也在以太坊基金會的GitHub中。
Github link; https://github.com/ethereum/web3.py
PyPi link; https://pypi.python.org/pypi/web3/4.0.0b9
Documentation link; https://web3py.readthedocs.io/
EthereumJS
以太坊的庫和實用程式集合。
Github link; https://github.com/ethereumjs
Website link; https://ethereumjs.github.io/
web3j
web3j 是Java和Android庫,用於與Ethereum客戶端集成並使用智能合約。
Github link; https://github.com/web3j/web3j
Website link; https://web3j.io
Documentation link; https://docs.web3j.io
Etherjar
Etherjar 是與Ethereum集成並與智能合約一起工作的另一個Java庫。它專為基於Java 8+的伺服器端項目而設計,提供RPC的低層和高層封裝,以太坊資料結構和智能合約訪問。
Github link; https://github.com/infinitape/etherjar
Nethereum
Nethereum 是以太坊的.Net集成庫。
Github link; https://github.com/Nethereum/Nethereum
Website link; http://nethereum.com/
Documentation link; https://nethereum.readthedocs.io/en/latest/
ethers.js
ethers.js 庫是一個緊湊,完整,功能齊全,經過廣泛測試的以太坊庫,完全根據MIT許可證獲得,並且已收到來自以太坊基金會的DevEx資助以擴展和維護。
GitHub link: https://github.com/ethers-io/ethers.js
Documentation: https://docs.ethers.io
Emerald Platform
Emerald Platform提供了庫和UI組件,可以在以太坊上構建Dapps。Emerald JS和Emerald JS UI提供了一組模塊和React組件來構建Javascript應用程式和網站,Emerald SVG Icons是一組區塊鏈相關的圖示。除了Javascript庫之外,它還有Rust庫來操作私鑰和交易簽名。所有Emerald庫和組件都使用 Apache 2許可。
Github link; https://github.com/etcdevteam/emerald-platform
Documentation link; https://docs.etcdevteam.com