如何通過建構以太坊智能合約來銷售商品?這是個問題。
毫無疑問,比特币已經改變了我們看待和了解什麼是金錢,價值以及最近由智能合約産生的所有權的方式。這很有趣,因為幾乎每個人都聽說過它或加密貨币。來自許多業務領域的人,不僅僅是我們,IT工作者。
在本文中,我将展示我關于以太坊的第一份智能合約,這是我對區塊鍊的個人研究的一部分。

區塊鍊适合初學者
有許多涉及區塊鍊技術的概念,但在本節中我将嘗試解釋這種驚人的颠覆性技術。
顧名思義,區塊鍊是使用它的哈希資料連接配接在一起的資料鍊的塊,由使用者的私鑰簽名。通常,這些塊的大小限制為1MB,并且由于此限制而存儲盡可能多的交易。
- 概念1
:它們是存儲交易的塊。認為這些塊是具有一些元組的表,每個塊都存儲交易。區塊
- 概念2
,公鑰和私鑰對:每個人都可以通路我們的公鑰,隻需我們通路我們的私鑰即可。并且,非對稱加密意味着:我們使用其中一個密鑰編碼,它隻能與另一個密鑰進行解碼。沒有例外。不對稱加密
真實性:如果我們想簽署資料,我們使用私鑰進行編碼,因為每個人都可以使用我們的公鑰解碼并安全地認證我們。但是沒有人可以改變資料并再次簽名,因為它會被命運所拒絕。當真實性成為問題時使用。這是區塊鍊的情況 。
- 使用私鑰,所有者對資料進行編碼,或者更好地對資料進行簽名 。 通過此操作,所有者保證沒有人僞造他或她的身份。
- 使用公鑰,每個人都可以解碼資料,或者更好地檢查 簽名 。 通過這種操作,起源就是我們所期待的。
- 概念3區塊鍊的
在于連結塊的機制:當生成新塊時,從目前塊的資料生成哈希,包括它的簽名。然後,生成新塊,将來自前一塊的hash與目前塊的資料組合,并生成新的hash并使用使用者的私鑰進行簽名,依此類推。如果有人試圖更改塊的資料以僞造事務,則他或她必須在整個網絡開始使所有這些重新生成的塊無效之前快速生成所有後續塊。不可侵犯性質
如同暗夜裡一開始沒有燈…
一切都從創世塊開始,這個塊負責啟動區塊鍊網絡并設定許多參數值,例如挖掘代币的難度。
如何建立鍊?
基于來自目前塊的所有資料(包括簽名),生成hash并将其包括在新生成的塊的頭中。此時此新塊将成為目前塊并開始注冊交易。
很驚人!是不是?
案例分析
我選擇了一個非常常見的用例,為使其易于了解,隻留下了智能合約邏輯和技術細節的實作。
企業對企業——B2B
- 零售商(retailer)從制造商(manufacturer)處訂購貨物。制造商檢查庫存數量,收集産品,包裝,準備和運輸。零售商和制造商有可信賴的商業關系。
- 貨物(shipment)由制造商要求的快遞公司(courier)發貨,他們也有可信賴的商業關系。
- 零售商(retailer)和快遞(courier)之間可信賴的商業關系(relationship)是可傳遞的(transitive),因為為制造商提供了共同的關系。
- 值得信賴(trusted)的商業關系(relationship)非常重要,因為傳統市場需要這種關系。從零售商到制造商的付款是在收到貨物後幾天發生的。并且,從發貨人到快遞員的付款在交貨确認後幾天發生。如果沒有信任,他們就不會互相信任,也不會做出交易。這并不會促進最佳價格,服務和産品的競争。
概括
最精細的商業交易由三部分組成:買方(buyer),貨物(goods)和賣方(seller)。最基本的過程是轉移貨物的所有權以換取現金,從賣方到買方。你怎麼看待這件事?
我們可以将此模型稱為:從賣家購買商品所有權(buy-goods-ownership-from-seller)或簡寫為bogos
讓我展示一些例子,然後翻譯成bogos模型。
- B2C——商品:John想要一部新的智能手機,他去了當地的市場并挑選了最好的智能手機并用他的信用卡付款。在這個例子中,“John”是買方
,“smartphone”是商品buyer
,“local mart”是賣方goods
。在John支付之前,本地市場擁有智能手機,付款後所有權轉移給他。seller
- B2C——服務:Maria很餓,她去了媽媽的意大利面并訂購了很多意大利面條。廚師接受她的訂單細節,準備菜肴,服務員為此服務。當Maria滿意時,她付賬并回家。在這個例子中,“Maria”是買家
,“dish”是商品buyer
,“Mama’s Pasta”是賣家goods
。支付後,“菜”的所有權從“Mama’s Pasta”轉移到“Maria”。seller
- C2C——貨物:Joseph在賣他的車。幾周後,Berta想要從他那裡買車。他們完成交易,Berta支付了有價值的價值,而Joseph将所有權轉讓給了她。 在這種情況下,“Berta”是買方
,“car”是貨物buyer
而“Joseph”是賣方goods
。支付後,所有權轉移到“Berta”。seller
- B2B——商品:Jong,買家
,是一家電子産品經銷商,有一家商店,他從賣家北京公司buyer
訂購商品seller
。當貨物準備好運輸時,它們被打包,一名叫海外的快遞員将包裹運給Jong。當他收到貨物和發票時,将執行付款。goods
智能合約解決方案
正如我們在案例研究部分所看到的,參與者之間的信任是傳統業務的主要關注點。這個概念證明的目标是使用以太坊區塊鍊網絡上的智能合約建立一種無信任的方式在參與者之間進行交易。
為了定義一系列交易,外部互動和支付,我提出了案例研究的新流程。
- 制造商(Manufacturer)專門為零售商(Retailer)的帳戶部署智能合約。
- 零售商(Retailer)在(Manufacturer)的智能合約中訂購産品X,其數量等于N.通過所謂的訂單發送活動,制造商(Manufacturer)可以接收訂單資料并對其進行處理。
- 制造商(Manufacturer)尋找
智能合約的最佳運費。Courier
- 制造商(Manufacturer)發送訂單價格,零售商(Retailer)通過發送的稱為價格的事件收到訂單價格。
- 制造商(Manufacturer)發送裝運價格,零售商(Retailer)通過發送的稱為價格的事件接收此價格。
- 零售商(Retailer)執行總額的安全支付:訂單價格+裝運價格。這些代币進入智能合約賬戶并等到那裡直到交貨。
- 制造商(Manufacturer)發送包含交貨日期和一些其他資料的發票。零售商(Retailer)通過發送的稱為發票的事件接收發票資料。
-
在将訂單傳遞給零售商(Retailer)後 ,标記了智能合約上的訂單。快遞員可以是機器人,也可以是無人機。想想我!今天我們有很多可能性。Courier
- 智能合約為訂單支付制造商的費用。
- 智能合約向快遞公司(Courier)支付為了發貨。
好的,足夠的理論,讓我們看看如何寫代碼!
開發工具
為了加速我們的發展,有一個很好的選擇叫做Truffle Framework。這個架構有很多東西可以幫助我們在以太坊程式設計語言Solidity中開發智能合約。
要快速檢視Solidity,我建議你通路以下網站:http://solidity.readthedocs.io/en/develop/solidity-by-example.html
Truffle
Truffle是一個用于編譯,測試和部署用Solidity編寫的智能合約到以太坊區塊鍊的工具。要使用它,我們需要nodejs。然後,檢查已安裝node tools的版本。
如果你的計算機中沒有nodejs,請按照這些說明操作 。
$ node -v
v6.11.5
$ npm -v
3.10.10
使用以下指令全局安裝Truffle。
$ sudo npm install -g truffle
檢查Truffle的版本輸入
truffle version
。
$ truffle version
Truffle v4.0.5 (core: 4.0.5)
Solidity v0.4.18 (solc-js)
ganache
全局安裝ganache CLI以在localhost上運作私有以太坊區塊鍊網絡。
$ sudo npm install -g ganache-cli
然後,嘗試在終端中輸入
ganache-cli
。你必須在localhost上看到類似于以下内容的8545端口。
$ ganache-cli
Ganache CLI v6.0.3 (ganache-core: 2.0.2)
Available Accounts
==================
(0) 0x8baae15bf75ffdb6fcde77ecc4e2aa8063ad820c
(1) 0x1f6c6fa7aceb8124e9db0bd283dbe99489cd7b80
(2) 0x85e1e869e57004618481539c1ee8b2a55195892b
(3) 0x05dd0af1306a4537ca25e651f97df23c68d9b2d7
(4) 0x84a9964a2a9d8136498b26f27311c1ecd244733a
(5) 0x79e21b3f20eca854fa6ca822a8550b1fbdda3c30
...
HD Wallet
==================
Mnemonic: stereo pistol pulp advance same transfer eight deal unhappy charge attitude lock
Base HD Path: m/44'/60'/0'/0/{account_index}
Listening on localhost:8545
開始之後,我們有十個賬戶(或錢包或位址),每個賬戶餘額為100.00ETH,還有一個完整的工作和私人區塊鍊,可以玩,試錯,用不完的以太币,做我們想做的一切,直到獲得穩定的代碼。
你想要一個更直覺的方式來看看發生的事情,然後安裝Ganache而不是ganache-cli。這個工具可以完成ganache-cli所做的工作,加上一個非常酷的GUI可以使用滑鼠點選。
這些工具,ganache-cli和Ganache GUI在關機後不能維護狀态,它們需要我們在每次重新開機時重新部署智能合約。
MyEtherWallet是一個對初學者來說很有趣的GUI,它比Ganache GUI更直覺,因為我們可以在下拉清單中選擇要調用的函數。它對于示範和截屏也非常有用。
MyEtherWallet隻是與以太坊區塊鍊互動的附加工具。我們必須先運作ganache-cli或Ganache GUI。在此處下載下傳包,解壓縮并在你喜歡的浏覽器中打開index.html檔案,并添加指向正在運作的區塊鍊的自定義節點。
設定
通過本文,我不會假裝展示如何成為Solidity程式員,但如果你想要啟動免費的項目,請按以下步驟操作。
$ mkdir my-contract
$ cd my-contract
$ truffle init
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!
Commands:
Compile: truffle compile
Migrate: truffle migrate
Test contracts: truffle test
要有效地部署合約,我們必須在
migrations
目錄中建立遷移檔案。下面我向你展示負責部署
Deal.sol
合同的
2_deploy_contract.js
檔案的内容。通過這種方法,我們可以将參數傳遞給合約構造函數以及許多其他可能性。
“use strict”;
var Deal = artifacts.require(“./Deal.sol”);
module.exports = function(deployer, network, accounts){
deployer.deploy(Deal, accounts[1]);
};
建立一個工作目錄。以下指令将在你的主目錄中建立區塊鍊目錄。
$ mkdir -p ~/blockchain
$ cd ~/blockchain
來吧看看代碼。将源代碼從https://github.com/fabiojose/ethereum-ex克隆到
~/blockchain
目錄中。
$ git clone https://github.com/fabiojose/ethereum-ex.git
$ cd ethereum-ex
安裝依賴項。
$ npm install
一個vanilla Truffle項目不需要npm安裝,但如果我們想要更多的庫,隻需建立一個
package.json
檔案并将依賴項放在那裡。
建構和部署
要執行Truffle指令,我們需要通路我們的私有區塊鍊。為此,編輯
truffle.js
檔案,添加以下行。
module.exports = {
networks: {
development: {
host: "localhost",
port: 8545,
network_id: "*"
}
}
};
預設情況下,Ganache GUI在端口号7545上綁定。如果你選擇它而不是ganache-cli,請更改為此端口。在Solidity中,我們需要編譯
.sol
檔案。為此,我們隻需在項目目錄中鍵入以下指令即可:
$ truffle compile
Compiling ./contracts/Deal.sol...
Writing artifacts to ./build/contracts
要部署我們編譯的
.sol
檔案,我們必須使用
migrate
指令。此指令将在
truffle.js
檔案中配置的網絡中部署智能合約。
$ truffle migrate
Using network 'development'.
Running migration: 1_initial_migration.js
Deploying Migrations...
... 0xa74ff1912d2a53a3d77d2678e9fc617f9baa838a46e57a4182d1da6ff4a0cc4f
Migrations: 0xd86037f19f3adac9bdf3331298b3e9709baabb2e
Saving successful migration to network...
... 0x221758e993424fa81581100e2cdd278ed45f9c84820f3ced69362813e409a098
Saving artifacts...
Running migration: 2_deploy_contracts.js
Deploying Deal...
... 0x16f5149e71dd77f8891278e824c9d6e477f7408253fbc2f36560da4aa2a7c6f0
Deal: 0x3c7396d30e70b4deec5b33582b59766249b6ea83
Saving successful migration to network...
... 0x0631419bcf68146a50f524b1d6735f62fca5a825858e57458d4f8cf45e0e70aa
Saving artifacts...
要更好地了解
migration
,請閱讀:http://truffleframework.com/docs/getting_started/migrations
測試
單元測試?:是的!我們可以通過智能合約進行單元測試。畢竟,一個簡單的錯誤可能導緻我們丢失所有代币。
在幕後我們有Mocha和Chai,主要差別在于使用關鍵字
contract
代替
describe
建立測試場景。
要執行測試,隻需在項目目錄中輸入以下指令即可。
$ truffle test
Using network 'development'.
Contract: Deal
✓ should the seller account owns the contract (72ms)
✓ should the second account was the buyer (72ms)
✓ should first order was number 1 (154ms)
✓ should the shipment price was set (189ms)
✓ should the order's price was set (169ms)
✓ should the safe pay was correct (218ms)
✓ should the contract's balance was correct after the safepay (186ms)
✓ should the first invoice was number 1 (177ms)
✓ should the invoice 1 it is for order 1 (190ms)
✓ should the courier was correct (186ms)
✓ should the contract's balance was correct after the delivery (268ms)
11 passing (2s)
可以像在本文中那樣在JavaScript中實作測試,并在Solidity中進行測試。你可以在此處獲得有關測試的更多詳細資訊:http://truffleframework.com/docs/getting_started/testing。
編碼
為了實施解決方案,我應用了泛化并使用這些實體:買方(buyer),賣方(seller),貨物(goods),訂單(order),發票(invoice)和稱為
Deal
的智能合約。你可以通過克隆源代碼來檢視具體實作。
賣方為每個想要與之進行交易的買方部署一個智能合約,即交易執行個體。為此,我們需要一個帶有一個參數的構造函數
constructor
:Buyer帳戶位址。
/// The smart contract’s constructor 智能合約的構造函數
function Deal(address _buyerAddr) public payable {
/// The seller is the contract’s owner 賣方是合約的所有者
owner = msg.sender;
buyerAddr = _buyerAddr;
}
請注意,與許多語言一樣,Solidity的構造函數具有相同的類名,或同名的合約。
contract Deal {
/// ...
}
要将參數傳遞給構造函數,我們使用位于
migrations/2_deploy_contracts.js
的部署檔案來執行此操作,這是我們調用
truffle compile
或
truffle test
時由
migrations/2_deploy_contracts.js
使用的.js檔案。
下面我們有
migration/2_deploy_contract.js
的内容。在第3行,我們需要為智能合約加載我們的Solidity實作。在第6行,我們使用由Truffle注入的部署執行個體來執行
Deal
的部署。而
deploy()
函數的第二個參數将傳遞給第一個構造函數參數。在這種情況下,我們從ganache提供的帳戶數組中傳遞第二個帳戶。
1. “use strict”;
2.
3. var Deal = artifacts.require(“./Deal.sol”);
4.
5. module.exports = function(deployer, network, accounts){
6. deployer.deploy(Deal, accounts[1]);
7. };
要發送商品訂單,我們有
sendOrder
功能。它是改變合約狀态的函數中無用的傳回資料,因為它們啟動将異步處理(或挖掘)的交易。隻是查詢合同狀态的函數可以傳回資料。
/// The function to send purchase orders 發送采購訂單的功能
/// requires fee 需要費用
/// Payable functions returns just the transaction object, with no custom field. 應付款函數隻傳回交易對象,沒有自定義字段。
/// To get field values listen to OrderSent event. 要擷取字段值,請監聽OrderSent事件。
function sendOrder(string goods, uint quantity) payable public {
/// ...
}
要擷取訂單号,在執行
sendOrder
之後我們必須監聽事件。在這種方法的情況下,我們必須使用以下簽名來監聽
OrderSent
。
/// Event triggered for every new order 為每個新訂單觸發事件
event OrderSent(address buyer, string goods, uint quantity, uint orderno);
實際上,對于每個更改合同狀态的函數,都會觸發事件以擷取新的資料狀态。對于序列圖中的每個階段,我們都有一個執行它的方法:
sendPrice
,
sendSafepay
,
sendInvoice
和
delivery
。零售商是買方,制造商是賣方。
完整的代碼被推送到我的Github:https://github.com/fabiojose/ethereum-ex 。
克隆它,玩得開心!
最後的話
現在是時候體驗智能合約的功能,試圖解決現實世界的問題。去吧,試試看,讓我知道!我們可以分享我們的實驗。
關于模式
在這一點上,我們應該關注一些模式。我注意到這兩個與部署方法有關。
- 部署一次,多次使用:這個工作就像一個應用程式,因為我們部署了一個智能合約版本并多次使用直到銷毀它。這是本文使用的方法。
- 一次部署,一次使用:在這種方法中,我們部署了一個智能合約的版本,一次性使用它,我們需要一個非常具體的目标并在最後銷毀。
參考
- http://solidity.readthedocs.io/en/develop/contracts.html
- http://solidity.readthedocs.io/en/develop/solidity-by-example.html
- https://vomtom.at/solidity-send-vs-transfer/
- https://zupzup.org/smart-contract-solidity/
- http://truffleframework.com/docs/getting_started/javascript-tests
======================================================================
分享一些以太坊、EOS、比特币等區塊鍊相關的互動式線上程式設計實戰教程:
- 以太坊入門教程,主要介紹智能合約與dapp應用開發,适合入門。
- 以太坊開發進階教程,主要是介紹使用node.js、mongodb、區塊鍊、ipfs實作去中心化電商DApp實戰,适合進階。
- java以太坊開發教程,主要是針對java和android程式員進行區塊鍊以太坊開發的web3j詳解。
- python以太坊,主要是針對python工程師使用web3.py進行區塊鍊以太坊開發的詳解。
- php以太坊,主要是介紹使用php進行智能合約開發互動,進行賬号建立、交易、轉賬、代币開發以及過濾器和交易等内容。
- C#以太坊,主要講解如何使用C#開發基于.Net的以太坊應用,包括賬戶管理、狀态與交易、智能合約開發與互動、過濾器和交易等。
- EOS教程,本課程幫助你快速入門EOS區塊鍊去中心化應用的開發,内容涵蓋EOS工具鍊、賬戶與錢包、發行代币、智能合約開發與部署、使用代碼與智能合約互動等核心知識點,最後綜合運用各知識點完成一個便簽DApp的開發。
- java比特币開發教程,本課程面向初學者,内容即涵蓋比特币的核心概念,例如區塊鍊存儲、去中心化共識機制、密鑰與腳本、交易與UTXO等,同時也詳細講解如何在Java代碼中內建比特币支援功能,例如建立位址、管理錢包、構造裸交易等,是Java工程師不可多得的比特币開發學習課程。
- php比特币開發教程,本課程面向初學者,内容即涵蓋比特币的核心概念,例如區塊鍊存儲、去中心化共識機制、密鑰與腳本、交易與UTXO等,同時也詳細講解如何在Php代碼中內建比特币支援功能,例如建立位址、管理錢包、構造裸交易等,是Php工程師不可多得的比特币開發學習課程。
- tendermint區塊鍊開發詳解,本課程适合希望使用tendermint進行區塊鍊開發的工程師,課程内容即包括tendermint應用開發模型中的核心概念,例如ABCI接口、默克爾樹、多版本狀态庫等,也包括代币發行等豐富的實操代碼,是go語言工程師快速入門區塊鍊開發的最佳選擇。
彙智網原創翻譯,轉載請标明出處。這裡是原文如何通過建構智能合約來銷售商品