我经常构建使用以太坊的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个字符。规范是什么意思?好吧,在以太坊中有规范类型和速记类型(例如uint256uint的规范类型)。我实际上不知道它们的定义在哪里,但是查看以太坊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的开发。

汇智网原创翻译,转载请标明出处。这里是原文

Web程序员如何入门以太坊开发相关推荐

  1. Web开发中软件工程艺术(Web程序员请进来谈谈,特别是有大型门户网站后台开发的程序员)

    近正着手一个大型综合性门户网站后台管理系统(准确说是内容管理系统)设计  与规划,对网站开发技术有一个较深刻的认识.从Internet的出现到现在,WebSite的开发技术有4个过程:        ...

  2. 以太坊开发入门,完整入门篇(小白可以看看,高手看看自己有没有遗漏的

    2019独角兽企业重金招聘Python工程师标准>>> 翻译自:https://medium.com/@mattcondon/getting-up-to-speed-on-ether ...

  3. 以太坊是什么 - 以太坊开发入门指南

    本文首发于深入浅出区块链社区 原文链接:以太坊是什么 - 以太坊开发入门指南 很多同学已经跃跃欲试投入到区块链开发队伍当中来,可是又感觉无从下手,本文将基于以太坊平台,以通俗的方式介绍以太坊开发中涉及 ...

  4. 第一课 以太坊开发从入门到精通学习导航

    辉哥认为,区块链是人类社会伟大的革命,改变了生产关系.但是作为技术人员,有必要了解全部底层技术和算法吗?依稀记得,以前有些培训机构培训使用电脑时先教五笔输入法,然后才开始学习使用WINDOWS,让很多 ...

  5. 以太坊开发入门--相关知识点说明

    架构 应用层 钱包-METAMASK 水龙头: 一.Ropsten测试网络 https://faucet.egorfine.com/ 每个地址每天只能获取一次 二.Kovan测试网 https://e ...

  6. 以太坊开发入门,如何搭建一个区块链DApp投票系统

    点击关注异步图书,置顶公众号 每天与你分享 IT好书 技术干货 职场知识 第一节 概述 对于初学者,需要了解以太坊开发相关的基本概念,另外就是如何构建一个基于以太坊的完整去中心化应用例如一个区块链投票 ...

  7. 以太坊开发入门实战视频教程-杨正威-专题视频课程

    以太坊开发入门实战视频教程-326人已学习 课程介绍         以太坊开发入门实战视频教程:从以太坊的安装使用,到rpc接口的调用,以及钱包应用开发所需要的知识(以java为例),智能合约的简单 ...

  8. 【以太坊开发06】Truffle开发入门

    ⼀.什么是truffle 1. 概述 truffle是世界级的以太坊开发框架,它使得以太坊开发变得简单⾼效,它具有以下特点: 内置智能合约编译.链接.开发和⼆进制管理. 快速开发的⾃动化合约测试 脚本 ...

  9. 在MacOS上构建以太坊开发环境

    以太坊是流行的区块链去中心化平台.作为本文的一部分,你将了解如何在MacOS平台上设置以太坊. 首先需要对区块链和以太坊有基本理解,即什么是以太坊之类的? 工具集 以太坊开发生态系统包括以下工具列表. ...

最新文章

  1. 智能音箱二战:国内Q1出货量5倍增长,BAX上屏、扩类、做家居
  2. 如何评估Serverless服务能力,这份报告给出了40条标准
  3. asp.net中条件查询+分页
  4. java dispatcher详解_dispatcherservlet初始化过程详解
  5. Linux进程管理:进程调度之完全公平调度算法
  6. Flutter实战一Flutter聊天应用(七)
  7. 计算机网络培养方案,计算机网络技术专业培养方案
  8. 虚拟机报错:collect.exe
  9. Turbo | 简介与安装
  10. 将超星阅读器的PDG格式文件转化成PDF格式
  11. WEB专用服务器的安全设置
  12. Spring核心模块及功能汇总
  13. 叮铃铃~: 一个Vue铃声/提示音组件
  14. silk lobe资源公众号_电视剧资源免费看公众号【推荐】
  15. 腾讯2019广告算法大赛总结
  16. APP兼容性专项测试
  17. 统计Nginx访问量
  18. Hibernate使用手册(官网)
  19. JavaScript高程三----(基础一)
  20. Angular入门到精通系列教程(15)- 目录结构(工程结构)推荐

热门文章

  1. nginx请求如何映射url
  2. crontab定时任务常见问题
  3. NGINX:nginx精准禁止特定国家或者地区IP访问
  4. VBA中让程序休眠 SLeep的方法
  5. 如何防止盗号 使用windows自带的 屏幕键盘 OSK
  6. 具体问题具体分析 之 QA票
  7. 【PostgreSQL-9.6.3】LOG: unrecognized configuration parameter dynamic_shared_memory_type
  8. 【SQL】ROWNUM和ROWID
  9. 【Oracle】删除手工创建的数据库
  10. Gson格式转换Integer变为Double类型问题解决