摘要:加入以太坊生态系统,一起征服世界。数字,字符串等要注意的第二件事是以太坊中的是位。一旦你掌握了这些东西,我个人会认为你是一个有能力的以太坊开发者
我经常构建使用以太坊的Web应用程序,我理所当然地认为每天都使用的是神奇的工具集。我们的生态系统正在迅速发展,我认为很多新人都感到不知所措。以太坊是一项了不起的技术,但它也是新生的,而且根本没有足够的时间让专业知识充分渗透。我希望人们知道以太坊开发实际上与现代Web开发人员工作流程非常兼容——将以太坊功能集成到任何Web应用程序中相对容易,你可以从今天开始。
因为我认为自己是以太坊的高手,可以向主流开发者展示方向,我决定将一堆分散的知识放到一个地方(我知道不是非常去中心化)。你当然需要在每一步都查阅相应的文档,但我希望本文将向你展示如何将所有内容(或多或少)放在一起。
如果你准备好学习,请让我为你提供方向和指南。加入以太坊生态系统,一起征服世界。
获取区块链有很多客户端可供选择,但我建议不要担心geth 、parity与pyethapp(即将到来的python客户端代表!)。对于那些只想要一个可复用的区块链以便可以开始构建东西(例如你)的人,我建议testrpc满足你的所有开发需求。安装完成后,可以使用以下命令启动它:
testrpc
恭喜你,这就有一个区块链了。请注意,默认情况下,testrpc不会挖掘块,但-b标志允许你指定块间隔(例如1秒)。我喜欢这种配置有很多原因,我不会介入,但请记住它是可用的。
与区块链交互一旦你的区块链旋转,你需要一种与它交谈的方法。 你可能已经下载了web3.js。 如果你没有,你必须下载新的。好吧,继续并确保安装了web3,然后打开一个config.js文件并将其放入其中:
var web3 = require("web3"); var web3_provider = "http://localhost:8545"; var _web3 = new web3(); _web3.setProvider(new web3.providers.HttpProvider(web3_provider)); exports.web3 = _web3;
任何时候你想与后端服务器上的区块链交互,只需要这样做:
var config = require("./config.js"); config.web3.eth.X
可以在此处找到X(即你想要的任何web3 API函数)。
写智能合约我会在这里为你节省一些时间:你将使用solidity来编写智能合约。如果你认为智能合约是可怕的,没必要。对于许多应用程序,只要遵循一条规则,它实际上非常简单:保持合约简单。
有两个原因,你总是始终保持合约绝对简单,因为必须这样:
每次计算/存储操作都需要gas,等于以太币,等于货币。我们正在谈论支付0.05美元和1.50美元之间的差异来调用你的合约。以太坊的观点不是要替换你的数据库(至少在我看来不是这样),所以保持逻辑简短和存储最小化。
更复杂=更多地方出错。当你的代码负责人们的钱并且无法回滚时,这很糟糕。请花一点时间只让有用的话写在其中。
好的,简单的合约——得到它。让我们继续。
部署智能合约如果你还没有听说过truffle,那么现在一定要看一下。我喜欢在truffle目录中管理我的测试者合约。关于这一点的巧妙之处在于,你可以轻松地将其用于测试框架。在package.json中考虑这个脚本:
"scripts": { "test": "cd truffle && truffle deploy && truffle test ./myTruffleTest.js && cd .. && npm run myOtherTests" }
这样做:1.部署合约,2.运行truffle测试,3.运行常规测试——所有这些都在同一个脚本中!
请注意,你的truffle测试是“特殊的”,因为它们会在测试范围内注入一堆很酷的区块链内容。有多种方法可以将此信息传递给你的测试套件的其余部分。我个人使用truffle测试将合约地址保存到配置文件中,然后将该配置导入到我常规mocha测试中。只要我有正确的地址,我就可以通过web3.js在任何测试中与我的合约进行交互。无论如何,你会发现什么最适合你。
回到主要内容。你可以通过转到truffle目录并键入以下内容来部署智能合约:
truffle deploy
请注意,testrpc必须在另一个窗口中运行!
这将打印你刚刚部署的合约的地址,稍后你将需要该地址。正如我所提到的,你总是可以在truffle测试中以编程方式保存这个地址,但是现在你可以将它复制并粘贴到你的config.js文件中:
exports.contract_addr = "0xe73e8e0a4442e140aea87a4b150ef07b82492500"进行智能合约调用
既然我们有合约,我们需要调用它。好的,这个看起来很简陋——我们将用纯十六进制字符串调用合约。当然有libraries可以让这更容易,但是当涉及到合约调用时,我就开始要讲课了。请记住,我是你的领路人。
首先要注意的是,所有内容都必须是十六进制的。数字,字符串等要注意的第二件事是以太坊中的words是256位。这意味着你需要用零填充所有内容到64个字符。需要注意的第三件事是必须在函数定义中规范地声明类型。
好吧,这真的挺乱。我们来看一个例子,更好理解:
function add(uint x, uint y) public constant returns (uint) { return x + y; }
假设你要做个加法如1加2,以下是你调用此函数的方法:
1.获取封装好的规范函数定义的keccak 256哈希的前4个字节。
说什么?好吧,我没有做到这一点,但你可以在这个网站上输入你的功能声明并取前8个字符。规范是什么意思?好吧,在以太坊中有规范类型和速记类型(例如uint256是uint的规范类型)。我实际上不知道它们的定义在哪里,但是查看以太坊ABI定义的例子以及这篇文章。
无论如何,这就是我们的定义:
add(uint256,uint256)
返回keccak256哈希:
771602f7f25ce61b0d4f2430f7e4789bfd9e6e4029613fda01b7f2c89fbf44ad
其中前4个字节(8个字符)是:
771602f7
2.将参数填充为256位
这个更容易掌握:
x = 1是:
0000000000000000000000000000000000000000000000000000000000000001
y = 2是:
0000000000000000000000000000000000000000000000000000000000000002
他们在一起是:
00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002
3.将所有内容打包在一起并添加0x前缀
自定义:
0x771602f700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002
现在我们有了有效负载,我们可以通过web3调用合约:
var config = require("./config.js"); var call = "0x771602f700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002" var to = config.contract_addr; var res = config.web3.eth.call({ to: to, data: call });
在那之后,你应该返回res=3。实际上,你会得到一个BigNumber对象:
res.toString() >"3"
你可能应该阅读此内容以了解有关在整个应用中使用BigNumbers的原因。
好的,你可以使用我之前提到的库。
等等,我们还没有完成!我刚刚告诉你如何调用合约。但是,如果你想写入些东西(即更新状态)怎么办?以上的是不行的!你需要使用私钥签署一个交易,但在此之前,你需要一些以太。
设置帐户我们回到truffle吧。在我们的测试中,需要添加如下内容:
var keys = require(`${process.cwd()}/../test/keys.json`); it("Should send me some ether.", function() { assert.notEqual(keys.me.addr, null); var eth = 1*Math.pow(10, 18); var sendObj = { from: accounts[0], value: eth, to: keys.me.addr } Promise.resolve(web3.eth.sendTransaction(sendObj)) .then(function(txHash) { assert.notEqual(txHash, null); return web3.eth.getBalance(keys.me.addr) }) .then(function(balance) { assert.notEqual(balance.toNumber(), 0); }) })
重要提示:我们实际发送1个以太,这与10^18 wei相同。我们总是使用wei值进行调用/交易。
现在,我在这里跳过一步。你需要先获得以太坊帐户,该帐户来自你生成的私人/公共密钥对。我喜欢使用eth-lightwallet在后端进行密钥管理。
为了简单起见,让我假装在不断增长的config.js中硬编码这个变量:
exports.me = { addr: "0x29f2f6405e6a307baded0b0672745691358e3ee6", pkey: "8c2bcfce3d9c4f215fcae9b215eb7c95831da0219ebfe0bb909eb951c3134515" }
强制性提醒:永远不要共享你的私钥,将其上传到github,或者如果有任何资金就将其发布在Medium上。
回到测试,你可以看到以太被从accounts[0](默认情况下有一堆以太)移动到你的配置文件中的me.addr。
与智能合约进行交易现在你的帐户已经有了一些以太,现在是时候花钱了。有三种方式可以用以太:
1.将其作为Value发送到另一个地址。
2.调用更新合约函数去更新网络状态,这需要gas来激励矿工处理你的更新。
3.调用更新合约状态,但也接受以太币来支付(仅供参考,用solidity修正)——将发送Value,你还必须支付gas费用。
我们接下来要做的是第2种。假设我们有以下函数来跟踪用户的余额:
function addUserBalance(uint balance) public returns (bool) { if (!accounts[msg.sender]) { throw; } if (accounts[msg.sender].balance + balance < accounts[msg.sender].balance) { throw; } accounts[msg.sender].balance += balance; return true; }
注意第二个if语句,这是必要的,因为加和减在solidity会导致数值溢出和下溢——小心!还要注意在函数范围内的未声明的msg对象。
当我们通过发送交易调用此函数时,我们要求更新网络的全局状态以说明以下内容:
在合约范围内,msg.sender帐户的余额已经增加了balance。
我们没有权力自己更新状态,所以需要一个矿工做这件事。我们用gas向他或她支付这项服务,这意味着付出以太。
要正确调用此函数,我们需要再次使用ABI:
addUserBalance(uint256) --> 22526328 --> 0x225263280000000000000000000000000000000000000000000000000000000000000001
我们使用这些数据来形成一个未签名的交易:
var data = "0x225263280000000000000000000000000000000000000000000000000000000000000001"; var nonce = config.web3.eth.getTransactionCount(keys.me.addr); var gasPrice = 20 * Math.pow(10, 9); var gasLimit = 100000; var txn = { from: config.me.addr, to: config.contract_address, gas: `0x${gasLimit.toString(16)}`, gasPrice: `0x${gasPrice.toString(16)}`, data: data, nonce: `0x${nonce.toString(16)}`, value: "0x0" }
如上所述,需要gas进行交易(即更新状态)。gas*gasPrice是矿工执行交易可能花费的金额。如果操作成本高于你提供的成本,则交易将不会更新状态,并且矿工将保留你的所有gas费用。如果使用的gas少于所用gas,则退还余额。
如果我们将此对象提交给网络,它将失败,因为没有证据表明我实际上正在授权此交易。谁知道,有些陌生人可能会将我的余额更新为10亿(虽然目前还不清楚为什么有人会这样做)。
无论如何,我需要做的是用我的私钥签署交易。还记得你在配置文件中内容,我告诉过你不要与任何人分享吗?这样做:
var Tx = require("ethereumjs-tx"); var privateKey = Buffer.from(config.me.pkey, "hex") var tx = new Tx(txn); tx.sign(privateKey); var serializedTx = tx.serialize();
在这里,使用我最喜欢的库之一,根据你的私钥签署一个交易对象。这应该返回如下内容:
0xf8aa808504a817c800830f424094a0f68379088f9aee95ba5c9d178693b874c4cd6880b844a9059cbb000000000000000000000000053b2188b0b100e68299708864e2ccecb62cdf0d000000000000000000000000000000000000000000000000000000746a5288001ca01f683f083c2d7c741a1218efc0144adc1749125a9ca53134b06353a8e4ef72afa07c50fb59647ff8b8895b75795b0f51de745fa5987b985f7d1025eb346755bca0
最后,我们可以通过web3将其提交给区块链。它将返回一个交易哈希,它只是提供的交易的哈希值(这非常重要的是,不能证明交易是成功的!)
var txHash = config.web3.eth.sendRawTransaction(raw_txn);
看起来像这样:
0xac8914ecb06b333a9e655a85a0cd0cccddb8ac627098e7c40877d27a130a7293
现在的这一步,严格来说是可选的,但对于验证你的交易是否已被接受和处理非常重要:获取你的交易收据。
var txReceipt = config.web3.eth.getTransactionReceipt(txHash);
如果返回null,则你的交易未被提取(可能是你使用错误的私钥进行了签名?)。如果它不为null,可能仍有各种其他失败情况,来看看你的交易。
好的,有一条线索——如果你的gasUsed等于发送的gas,则意味着你的函数调用失败了。这意味着1.你没有提供足够的gas或者同时2.你的合约遇到了throw。
总结我知道,这是很多内容。
如果你感觉太多了,我建议你慢慢来,并使用这篇文章作为参考。你可能需要花费大量时间阅读文档。
也就是说,我上面描述的是80%的内容。一旦你掌握了这些东西,我个人会认为你是一个有能力的以太坊开发者。
如果你有兴趣,可以开始修修补补!这些工具变得越来越好,并且从未如此容易地进入。欢迎上岸。
更新:我已经为你创建了一个repo来展示本文中介绍的大部分内容。
如果希望快速进行以太坊开发,那请看我们精心打造的教程:
以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。
其他区块链教程如下:
以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和事件等内容。
C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和事件等。
php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。
EOS入门教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。
汇智网原创翻译,转载请标明出处。这里是原文
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/24309.html
摘要:加入以太坊生态系统,一起征服世界。数字,字符串等要注意的第二件事是以太坊中的是位。一旦你掌握了这些东西,我个人会认为你是一个有能力的以太坊开发者 我经常构建使用以太坊的Web应用程序,我理所当然地认为每天都使用的是神奇的工具集。我们的生态系统正在迅速发展,我认为很多新人都感到不知所措。以太坊是一项了不起的技术,但它也是新生的,而且根本没有足够的时间让专业知识充分渗透。我希望人们知道以太...
摘要:以太坊,主要讲解如何使用开发基于的以太坊应用,包括账户管理状态与交易智能合约开发与交互过滤器和事件等。 Android应用程序以太坊钱包生成,要做的工作不少,不过如果我们一步一步来应该也比较清楚: 1.在app/build.gradle中集成以下依赖项: compile (org.web3j:core-android:2.2.1) web3j核心是用于从服务器下载以太坊区块链数据的核心...
摘要:以太坊,主要讲解如何使用开发基于的以太坊应用,包括账户管理状态与交易智能合约开发与交互过滤器和事件等。 Android应用程序以太坊钱包生成,要做的工作不少,不过如果我们一步一步来应该也比较清楚: 1.在app/build.gradle中集成以下依赖项: compile (org.web3j:core-android:2.2.1) web3j核心是用于从服务器下载以太坊区块链数据的核心...
摘要:是企业与区块链相遇的地方。的框架旨在成为开发区块链解决方案的支柱。以太坊,主要是针对工程师使用进行区块链以太坊开发的详解。 如果你想将区块链合并到一个Java项目中,现在我们来看看就是这个细分领域中三个最大的OSS玩家。 好的伙计们,我们都听说过比特币,以太坊或其他加密货币,其中有一些时髦的名字围绕着我们常见的新闻,但我们作为Java开发人员知道如何轻松地与这些区块链技术进行交互吗?以...
阅读 1259·2021-09-22 15:00
阅读 3291·2019-08-30 14:00
阅读 1204·2019-08-29 17:27
阅读 1205·2019-08-29 16:35
阅读 666·2019-08-29 16:14
阅读 2020·2019-08-26 13:43
阅读 2057·2019-08-26 11:35
阅读 2294·2019-08-23 15:34