IT男 2019-06-29
如何通过构建以太坊智能合约来销售商品?这是个问题。
毫无疑问,比特币已经改变了我们看待和理解什么是金钱,价值以及最近由智能合约产生的所有权的方式。这很有趣,因为几乎每个人都听说过它或加密货币。来自许多业务领域的人,不仅仅是我们,IT工作者。
在本文中,我将展示我关于以太坊的第一份智能合约,这是我对区块链的个人研究的一部分。
有许多涉及区块链技术的概念,但在本节中我将尝试解释这种惊人的颠覆性技术。
顾名思义,区块链是使用它的哈希数据连接在一起的数据链的块,由用户的私钥签名。通常,这些块的大小限制为1MB,并且由于此限制而存储尽可能多的交易。
区块
:它们是存储交易的块。认为这些块是具有一些元组的表,每个块都存储交易。不对称加密
,公钥和私钥对:每个人都可以访问我们的公钥,只需我们访问我们的私钥即可。并且,非对称加密意味着:我们使用其中一个密钥编码,它只能与另一个密钥进行解码。没有例外。真实性:如果我们想签署数据,我们使用私钥进行编码,因为每个人都可以使用我们的公钥解码并安全地认证我们。但是没有人可以改变数据并再次签名,因为它会被命运所拒绝。当真实性成为问题时使用。这是区块链的情况 。
不可侵犯性质
在于链接块的机制:当生成新块时,从当前块的数据生成哈希,包括它的签名。然后,生成新块,将来自前一块的hash与当前块的数据组合,并生成新的hash并使用用户的私钥进行签名,依此类推。如果有人试图更改块的数据以伪造事务,则他或她必须在整个网络开始使所有这些重新生成的块无效之前快速生成所有后续块。如同暗夜里一开始没有灯......
一切都从创世块开始,这个块负责启动区块链网络并设置许多参数值,例如挖掘代币的难度。
如何创建链?
基于来自当前块的所有数据(包括签名),生成hash并将其包括在新生成的块的头中。此时此新块将成为当前块并开始注册交易。
很惊人!是不是?
我选择了一个非常常见的用例,为使其易于理解,只留下了智能合约逻辑和技术细节的实现。
企业对企业——B2B
最精细的商业交易由三部分组成:买方(buyer),货物(goods)和卖方(seller)。最基本的过程是转移货物的所有权以换取现金,从卖方到买方。你怎么看待这件事?
我们可以将此模型称为:从卖家购买商品所有权(buy-goods-ownership-from-seller)或简写为bogos
让我展示一些例子,然后翻译成bogos模型。
buyer
,“smartphone”是商品goods
,“local mart”是卖方seller
。在John支付之前,本地市场拥有智能手机,付款后所有权转移给他。buyer
,“dish”是商品goods
,“Mama's Pasta”是卖家seller
。支付后,“菜”的所有权从“Mama's Pasta”转移到“Maria”。buyer
,“car”是货物goods
而“Joseph”是卖方seller
。支付后,所有权转移到“Berta”。buyer
,是一家电子产品经销商,有一家商店,他从卖家北京公司seller
订购商品goods
。当货物准备好运输时,它们被打包,一名叫海外的快递员将包裹运给Jong。当他收到货物和发票时,将执行付款。正如我们在案例研究部分所看到的,参与者之间的信任是传统业务的主要关注点。这个概念证明的目标是使用以太坊区块链网络上的智能合约建立一种无信任的方式在参与者之间进行交易。
为了定义一系列交易,外部交互和支付,我提出了案例研究的新流程。
Courier
智能合约的最佳运费。Courier
在将订单交付给零售商(Retailer)后 ,标记了智能合约上的订单。快递员可以是机器人,也可以是无人机。想想我!今天我们有很多可能性。好的,足够的理论,让我们看看如何写代码!
为了加速我们的发展,有一个很好的选择叫做Truffle Framework。这个框架有很多东西可以帮助我们在以太坊编程语言Solidity中开发智能合约。
要快速查看Solidity,我建议你访问以下网站:http://solidity.readthedocs.io/en/develop/solidity-by-example.html
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 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 。
克隆它,玩得开心!
现在是时候体验智能合约的功能,试图解决现实世界的问题。去吧,试试看,让我知道!我们可以分享我们的实验。
在这一点上,我们应该关注一些模式。我注意到这两个与部署方法有关。
======================================================================
分享一些以太坊、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语言工程师快速入门区块链开发的最佳选择。
汇智网原创翻译,转载请标明出处。这里是原文如何通过构建智能合约来销售商品