当前位置: 首页 > 后端技术 > Node.js

Web程序员如何开始以太坊开发

时间:2023-04-04 00:43:16 Node.js

我经常构建使用以太坊的Web应用程序,并且我认为我每天使用的惊人工具集是理所当然的。我们的生态系统正在快速发展,我认为很多新人都感到不知所措。以太坊是一项了不起的技术,但它也是新生的,而且还没有足够的时间让专业知识充分渗透。我想让人们知道,以太坊开发实际上与现代Web开发人员的工作流程非常兼容——将以太坊功能集成到任何Web应用程序中相对容易,您可以从今天开始。由于我认为自己是以太坊高手并且可以向主流开发人员指明方向,所以我决定将一堆去中心化知识放在一个地方(不是很去中心化,我知道)。您当然需要在每个步骤中查阅相应的文档,但我希望本文将向您展示如何(或多或少)将所有内容放在一起。如果您准备好学习,请让我为您提供方向和指导。加入以太坊生态系统,一起征服世界。有很多客户端可以选择获取区块链,但我建议不要担心geth、parity和pyethapp(即将推出代表python的客户端!)。对于那些只想要一个可重用的区块链以便他们可以开始构建东西的人(像你一样),我推荐testrpc来满足你的所有开发需求。安装完成后,可以通过以下命令启动:testrpc恭喜,区块链有了。请注意,默认情况下,testrpc不挖掘块,但-b标志允许您指定块间隔(例如1秒)。我喜欢这种配置的原因有很多,我不会深入探讨,但请记住它是可用的。与区块链交互一旦你的区块链启动起来,你就需要一种与之对话的方式。您可能已经下载了web3.js。如果您没有,则必须下载一个新的。好的,继续并确保安装了web3,然后打开一个config.js文件并将其放入:varweb3=require('web3');varweb3_provider='http://localhost:8545';var_web3=新的web3();_web3.setProvider(新的web3.providers.HttpProvider(web3_provider));exports.web3=_web3;任何时候你想在后端服务器上与区块链交互,只需执行:varconfig=require('./config.js');config.web3.eth.XX可以在这里找到(即你想要的任何web3API函数)。编写智能合约我会在这里为您节省一些时间:您将使用solidity来编写智能合约。如果您认为智能合约很可怕,那您大可不必。对于许多应用程序,只要遵循一个规则,它实际上非常简单:保持契约简单。你总是保持你的合同绝对简单有两个原因,因为它必须是:每个计算/存储操作都需要气体,等于以太币,等于货币。我们谈论的是支付0.05美元和1.50美元之间的差额来调用您的合约。Ethereum的目的不是取代你的数据库(至少在我看来不是),所以保持逻辑简短和存储最少。更多的复杂性=更多的事情可能会出错。当您的代码对人们的钱负责并且无法回滚时,这很糟糕。请花点时间只在其中写下有用的词。好的,简单的合同-得到它。让我们继续。部署智能合约如果您还没有听说过truffle,那么现在一定要了解一下。我喜欢在truffle目录中管理我的测试员合约。这样做的好处是您可以轻松地将其用于测试框架。考虑package.json中的这个脚本:"scripts":{"test":"cdtruffle&&truffledeploy&&truffletest./myTruffleTest.js&&cd..&&npmrunmyOtherTests"}这样做:1.部署合约,2.运行松露测试,3.运行常规测试——全部在同一个脚本中!请注意,您的松露测试是“特殊的”,因为它们将一堆很酷的区块链内容注入测试范围。有多种方法可以将此信息传达给测试套件的其余部分。我个人使用truffle测试将合约地址保存到配置文件中,然后将该配置导入到我的常规mocha测试中。只要我有正确的地址,我就可以在任何测试中通过web3.js与我的合约进行交互。无论如何,您会找到最适合您的方法。回到主要内容。您可以通过转到truffle目录并键入以下内容来部署智能合约:truffledeploy请注意,testrpc必须在另一个窗口中运行!这将打印您刚刚部署的合约的地址,稍后您将需要它。正如我提到的,您始终可以在truffle测试中以编程方式保存此地址,但现在您只需将其复制并粘贴到您的config.js文件中:合同,我们需要调用它。好吧,这个看起来很粗糙——我们将用普通的十六进制字符串调用合约。当然有图书馆可以使这更容易,但在合同电话方面,我开始讲课。记住,我是你的向导。首先要注意的是,一切都必须是十六进制的。关于数字、字符串等需要注意的第二件事是以太坊中的单词是256位。这意味着您需要将所有内容零填充到64个字符。第三点要注意的是,类型必须在函数定义中规范地声明。好吧,这真是一团糟。让我们看一个例子更好地理解:functionadd(uintx,uinty)publicconstantreturns(uint){returnx+y;}假设你想做一个加法,比如1加2,下面是你如何调用这个函数方法:1.获取封装规范函数定义的keccak256hash的前4个字节。说什么?好吧,我没有那样做,但是您可以在此站点上键入您的函数声明并取前8个字符。规范是什么意思?好吧,在以太坊中有规范类型和简写类型(例如uint256是uint的规范类型)。我实际上并不知道它们的定义位置,但请查看以太坊ABI定义以获取示例以及这篇文章。Anyway,here'sourdefinition:add(uint256,uint256)returnsthekeccak256hash:771602f7f25ce61b0d4f2430f7e4789bfd9e6e4029613fda01b7f2c89fbf44adwherethefirst4bytes(8characters)are:771602f72.Padtheargumentsto2:x=1Thisiseasiertograsp是:0000000000000000000000000000000000000000000000000000000000000001y=2是:0000000000000000000000000000000000000000000000000000000000000002他们在一起是:000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000023.将所有内容打包在一起并添加0x前缀自定义:0x771602f700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002现在我们有了有效负载,我们可以通过web3调用合约:varconfig=require('./config.js');varcall='0x771602f700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002'varto=config.contract_addr;varres=config.web3.eth.call({to:to,data:call});在那之后,你应该返回res=3.事实上,您将返回一个BigNumber对象:res.toString()>'3'您可能应该阅读此内容以了解为什么在整个应用程序中使用BigNumbers。好的,你可以使用我之前提到的库。等等,我们还没有完成!我刚刚告诉你如何调用合约。但是如果你想写一些东西(即更新状态)怎么办?以上不能接受!您需要使用您的私钥签署交易,但在此之前,您需要一些以太币。设置帐户让我们回到松露。在我们的测试中,我们需要添加以下内容:varkeys=require(`${process.cwd()}/../test/keys.json`);it('应该给我发送一些以太币。',function(){assert.notEqual(keys.me.addr,null);vareth=1*Math.pow(10,18);varsendObj={from:accounts[0],value:eth,to:keys.me.地址}Promise.resolve(web3.eth.sendTransaction(sendObj)).then(function(txHash){assert.notEqual(txHash,null);returnweb3.eth.getBalance(keys.me.addr)}).then(function(balance){assert.notEqual(balance.toNumber(),0);})})重要说明:我们实际上发送了1个以太币,相当于10^18wei。我们总是使用wei值进行调用/交易。现在,我在这里跳过一步。您需要先获得一个以太坊帐户,该帐户来自您生成的私钥/公钥对。我喜欢在后端使用eth-lightwallet进行密钥管理。为了简单起见,让我假装在不断增长的config.js中硬编码这个变量:exports.me={addr:"0x29f2f6405e6a307baded0b0672745691358e3ee6",pkey:"8c2bcfce3d9c4f215fcae9b215eb7c95831da0219ebfe0bb909eb951c3134515"}强制性提醒:永远不要共享你的私钥,将上传到github,有资助的话发到Medium上。回到测试中,您可以看到以太币从accounts[0](默认情况下有一堆以太币)移动到配置文件中的me.addr。使用智能合约进行交易现在您的帐户中已经有了一些以太币,是时候花掉它了。有三种花费以太币的方式:1.将它作为价值发送到另一个地址。2.调用更新合约函数更新网络状态,需要gas来激励矿工处理你的更新。3.调用更新合约状态,同时接受以太币作为付款(仅供参考,更正为solidity)——Value将被发送,同时你还必须支付gas费。接下来我们要做的是类型2。假设我们有以下函数来跟踪用户余额:functionaddUserBalance(uintbalance)publicreturns(bool){if(!accounts[msg.sender]){}if(accounts[msg.sender].balance+balance22526328-->0x225263280000000000000000000000000000000000000000000000000000000000000001我们使用这些数据来形成一个未签名的交易:vardata='0x225263280000000000000000000000000000000000000000000000000000000000000001';varnonce=config.web3.eth.getTransactionCount(keys.me.addr);vargasPrice=20*Math.pow(10,9);vargasLimit=100000;vartxn={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亿(尽管不清楚为什么有人会这样做)。无论如何,我需要做的就是用我的私钥签署交易。还记得你在配置文件中放了什么吗,我告诉过你不要与任何人共享它?这样做:varTx=require('ethereumjs-tx');varprivateKey=Buffer.from(config.me.pkey,'hex')vartx=newTx(txn);tx.sign(私钥);varserializedTx=tx.serialize();Here,useoneofmyfavoritelibrariestosignatransactionobjectbasedonyourprivatekey.这应该返回如下内容:0xf8aa808504a817c800830f424094a0f68379088f9aee95ba5c9d178693b874c4cd6880b844a9059cbb000000000000000000000000053b2188b0b100e68299708864e2ccecb62cdf0d000000000000000000000000000000000000000000000000000000746a5288001ca01f683f083c2d7c741a1218efc0144adc1749125a9ca53134b06353a8e4ef72afa07c50fb59647ff8b8895b75795b0f51de745fa5987b985f7d1025eb346755bca0最后,我们可以通过web3将其提交给区块链。Itwillreturnatransactionhash,whichisjust提供交易的哈希值(这个很重要,并不能证明交易成功!)vartxHash=config.web3.eth.sendRawTransaction(raw_txn);看起来像这样:0xac8914ecb06b333a9e655a85a0cd0cccddb8ac627098e7c40877d27a130a7293现在这一步,严格来说是可选的,但对于验证您的交易是否被接受和处理非常重要:获取您的交易收据。vartxReceipt=config.web3.eth.getTransactionReceipt(txHash);如果它返回null,则您的交易未被提取(也许您使用错误的私钥对其进行了签名?)。如果它不为空,可能仍然有各种其他失败情况来查看您的交易。好的,一条线索-如果您的gasUsed等于发送的gas,则意味着您的函数调用失败。这意味着1.你没有提供足够的gas或者同时2.你的合约遇到了抛出。总结一下我知道,内容很多。如果你觉得太多了,我建议你慢慢来,把这篇文章作为参考。您可能需要花费大量时间阅读文档。也就是说,我上面描述的是我正在描述的80%。一旦你掌握了这些东西,我个人会认为你是一个有能力的以太坊开发者。如果你感兴趣,就开始修补吧!这些工具一直在变得更好,并且访问从未如此简单。欢迎上岸。更新:我已经为您创建了一个存储库来演示本文中涵盖的大部分内容。如果你想快速开发以太坊,请看看我们精心制作的教程:以太坊入门,主要介绍智能合约和dapp应用开发,适合入门。其他区块链教程如下:以太坊开发进阶教程,主要介绍使用node.js、mongodb、blockchain、ipfs实现去中心化电商DApp实战,适合进阶。Java以太坊开发教程,主要为java和android程序员讲解区块链以太坊开发的web3j详解。PythonEthereum,主要供python工程师使用web3.py详细开发区块链以太坊。php以太坊主要介绍使用php进行智能合约开发交互、账户创建、交易、转账、代币开发、过滤器和事件等。C#以太坊主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态和交易、智能合约开发和交互、过滤器和事件等。Php比特币开发教程,本课程面向初学者,内容涵盖比特币的核心概念,如区块链存储、去中心化共识机制、密钥和脚本,交易和UTXO等,还详细讲解了如何使用Php在代码中集成比特币支持功能,如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习教程。EOS入门教程,本课程帮助您快速上手开发EOS区块链去中心化应用,涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后利用所有知识点完成一个便签DApp的开发。汇智网原创翻译,转载请注明出处。这里是原文