Zhuang's Diary

言之有物,持之以恒

目录

  1. 迈出第一步

  2. 与合约进行交互

  3. 现实世界中的构架和工具

2.尝试与合约进行交互

2.1以太坊智能合约介绍

阅读到这里,对以太坊已经有了基础的了解,已经与以太坊节点进行了交互,并在账户之间发送了一些交易等等。但除此之外,让以太坊如此惊艳的还有:智能合约。

正如我在简介中所说,智能合约是一个运行在以太坊虚拟机(EVM)上的程序。你可以创建智能合约来做任何你想做的事情,但是在今天,大多数智能合约都被用于像I-C-Os或者代币销售那样的众筹工具。接下来请允许我解释这些概念。

从众筹开始说起,相信这是一个你非常熟悉的概念。举办众筹活动的项目,其目的是为了开展项目而筹集资金。你可以几乎零成本的发行一种与你的项目相关的数字资产,并将其出售给任何人。这就是我们所说的初始代币发行(I-C-O)。

要想实现一个具有智能合约的I-C-O,你只需要实现使你的数字资产可交易并且有价值的逻辑。这听起来不错,这些就是以太坊代币,是以太坊生态系统中的一种数字资产。

接下来让我们试着通过一个例子来分析这些例子。

假设你的健康食品公司想要推出一种新的品牌。你决定进行一次I-C-O来筹集20,000个ETH。你用10个代币换取你收集到的每个ETH,并承诺,贡献者可以在你的商店使用这些代币购买食物。为此,你需要开发一个代币智能合约为每个贡献者存储他们相应的代币数量。

现在,假设你筹集到了这笔钱,开展了你的项目并开了你的第一家店。然后,你决定每份沙拉以1个代币的价格出售。一周以后,你的客人越来越多,但是沙拉的供应却是有限的,客人意识到这一点并开始把你的代币当作资产交易,从而提高了其市场价值。

这一过程在现实生活中实际存在,因为以太坊几乎允许任何人创建他们自己的可交易的数字资产。

2.2你的第一个智能合约

让我们看看如何建立一种基本的以太坊代币吧。我将通过这个例子介绍一些Solidity的基础知识。

请记住这个例子仅用于学习,不能使用它从事商业活动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
pragma solidity ^0.4.0;
contract MyToken {
address public creator;
uint256 public totalSupply;
mapping (address => uint256) public balances;

function MyToken() public {
creator = msg.sender;
totalSupply = 10000;
balances[creator] = totalSupply;
}

function balanceOf(address owner) public constant returns(uint256){
return balances[owner];
}

function sendTokens(address receiver, uint256 amount) public returns(bool){
address owner = msg.sender;

require(amount > 0);
require(balances[owner] >= amount);

balances[owner] -= amount;
balances[receiver] += amount;
return true;
}
}

让我们一步步来。pragma关键词显示了你使用的源码的Solidity版本。然后,用合约的名字进行合约定义初始化,在这个例子中,名字就是MyToken

接下来,你可以看到三个变量:

creator 是一个地址变量,用于存储该合约的拥有者。

TotalSupply 是一个256位的无符号整数,用于存储愿意与投资者共享的代币总数。

balance 是从地址到无符号整数的映射,其记录着每个投资者的余额。

之后,你将看到构造函数。正如你所见,这是一个与合约同名的函数,同时每当该合约的一个新的实例被部署在网络中时它将被调用一次。这就是合约的所有者被存储的地方。由于所有的函数调用都是一笔交易,因此可以通过交易的发送者即 msg.sender 获得合约的所有者信息。这个合约定义了总共10,000个代币。

下一个函数十分简单:balanceOf 用于展示参数指定的地址的余额。也许你想知道 constant 关键字是什么意思。这是因为Solidity的函数分为两种,一种是常量函数,一种是非常量函数。

非常量函数执行后状态会发生变化。另一方面,常量函数只读一次,这意味着它不执行任何状态转换,而是只读取数据。实际上,共有两种类型的常量函数:

view 声明函数承诺不修改状态(常量的别名)

pure 声明函数承诺不读取或者修改状态

sendTokens 函数允许我们在地址间交换代币。这是一个非常量函数或者说是一个交易函数,因为使用这个函数将改变余额。该函数的参数是接收者的地址以及欲转移的代币数量,函数的返回值是一个表示交易是否成功执行的布尔(Boolean)类型数据。你可以跳过第一行,它只是把函数的发送者保存在owner变量中。

接下来,你将看到两个先决条件:

1
2
3
4
...
require(amount > 0);
require(balances[owner] >= amount);
...

Require 是你可以用来检查条件或者进行验证的方法之一。它将评估一个条件并在条件不满足时恢复原状。因此,在这个例子中,要求被转移的代币 amount 大于零,同时要保证发送者有足够的余额来支付该笔代币转移。

最后,你要从 owner 的余额中减去交易转移的代币数量,并将其添加到 receiver 的余额中:

1
2
3
4
5
...
balances[owner] -= amount;
balances[receiver] += amount;
return true;
}

2.3 部署智能合约

现在让我们开始试着玩一下智能合约吧!首先需要在网络上部署智能合约。为了实现部署,需要使用名为 solc的Solidity编译器用于编译node.js。你可以通过以下指令安装它:

1
npm install -g solc

创建一个叫做 MyToken.sol 的文件并把合约代码粘贴到文件中,并在放置该文件的路径下打开一个控制终端。首先,通过运行以下指令编译文件:

1
solcjs MyToken.sol --bin

执行完该指令,编译器将创建一个 MyToken_sol_MyToken.bin 文件作为输出。你可以看到该文件只包含字节码。接着,你将需要使用solc来构建ABI(应用二进制接口),它是合约的接口或者说模板,通过它你可以获得可用的方法。这就是与Web3的联系点。你只需要运行:

1
solcjs MyToken.sol --abi

接着,你将看到一个叫做 MyTolen_sol_MyToken.abi 的新文件,其中包含的JSON内容定义了你的合约的接口。

最后,你只需要使用在后台运行的 testrpc ,通过node.js控制台部署你的合约。你完成了这些工作后,我们就开始初始化 web3 吧:

1
2
3
4
//instance web3
Web3 = require('web3')
provider = new Web3.providers.HttpProvider("http://localhost:8545")
web3 = new Web3(provider)

Web3 为你提供了解析合约ABI的可能性,并提供了一个JavaScriot API 与之交互。接着,你只需使用字节码就可以将该合约的一个新实例部署到 testrpc 上。请按照下面的命令输入:

1
2
3
4
5
6
7
8
9
10
// load files
myTokenABIFile = fs.readFileSync('MyToken_sol_MyToken.abi')
myTokenABI = JSON.parse(myTokenABIFile.toString())
myTokenBINFile = fs.readFileSync('MyToken_sol_MyToken.bin')
myTokenByteCode = myTokenBINFile.toString()
//deploy
account = web3.eth.accounts[0]
MyTokenContract = web3.eth.contract(myTokenABI)
contractData = { data: myTokenByteCode, from: account, gas: 999999 }
deployedContract = MyTokenContract.new(contractData)

最后,你可以通过调用 deployedContract.address 检查新部署的合约地址。请保存该地址,因为将需要使用这个地址与你的合约进行交互 :) 。

2.4 Web3与智能合约

让我们从搜索你的 testrpc 账户余额开始。为此,你首先需要访问已部署的合约实例:

1
2
3
4
5
6
contractAddress = deployedContract.address
instance = MyTokenContract.at(contractAddress)
web3.eth.accounts.forEach(address => {
tokens = instance.balanceOf.call(address)
console.log(address + ": " + tokens)
})

正如我们所预期的,第一个账户拥有所有的代币。太棒了!接下来,让我们将一部分代币转移到其他账户:

1
2
3
4
5
6
7
8
9
10
// send tokens
amount = 10
from = web3.eth.accounts[0]
to = web3.eth.accounts[1]
transactionHash = instance.sendTokens(to, amount, { from: from })
// checkout balances again
web3.eth.accounts.forEach(address => {
tokens = instance.balanceOf.call(address)
console.log(address + ": " + tokens)
})

你应该可以看到,现在第二个地址有了10个代币!你也可以搜索交易信息,正如你在本指南第一部分所做的那样:

1
web3.eth.getTransaction(transactionHash)

我还为这个mini DApp设计了一个简单的UI,你可以在这里看到它。你将看到一个包含了我们合约ABI的 MyToken.json 文件。我只是把solidity编译器生成的ABI的内容粘贴到这里面。你还可以看到一个与前一个应用相似的 app.js 文件,但是这个app.js文件还包含了我刚刚向你展示的用于发送代币以及展示账户代币余额详细信息的逻辑。

开发的用来测试 MyToken 转账的 DApp 的 UI

你也可以下载这个 App 并开始与它游戏。你将被要求提供你开发的合约案例的地址。

注意:为了减轻术语负担,这篇文章中描述的代币并非ERC20标准的代币。如果你不知道什么是ERC20协议代币,我们会在下一篇文章中解释它。

原文链接: https://blog.zeppelin.solutions/a-gentle-introduction-to-ethereum-programming-part-2-7bbf15e1a953

作者: Facu Spagnuolo

目录

  1. 迈出第一步

  2. 与合约进行交互

  3. 现实世界中的构架和工具

第一步

假设你已经有一些计算机编程方面的基础知识,并知道区块链数据结构是怎样的。如果不具备,请先了解ethfans的内容再回来看这篇博客。

以太坊

以太坊是一个开源的,分布式的,基于区块链技术的公共平台,无需审查及第三方干扰即可运行应用程序。

智能合约

智能合约仅仅是电脑程序。我们基于智能合约创建以太坊应用。虽然这个概念现在随着以太坊大红大紫,但是它实际上是由Nick Szabo于1996年提出。

EVM 以太坊虚拟机

EVM 是以太坊智能合约的沙盒运行时,是一个完全独立的环境。这意味着每个在EVM中运行的智能合约无法连接网络,无法调用文件系统和其他进程。

Gas

鉴于以太坊是一个分布式平台,所以必须有一种方式来限定智能合约的可用资源,否则整个网络的算力瘫痪都可能会被耗尽。Gas 通过为EVM中的每个指令确定执行成本来解决问题。重要的是,网络中的每笔交易都有一个“Gas预算”。如果预算的Gas用完了,交易将以失败告终,但是这笔交易仍然会被加载到区块链中。

Ether(ETH)

这是以太坊的加密数字货币。Gas/Ether的兑换价格用来衡量一个操作将花费多少ETH。执行交易所需支付的费用通过Gas用量与Gas价格相乘得出(计算所得的费用将使用ETH支付)。你可以将交易的Gas价格设置为任何值。但是,如果你设置的Gas价格太低的话,没有人会执行你的代码。

账户

每个账户都是由一个地址标识的。同一地址空间由两种账户共享。一种是由公私钥对控制的外部账户,该账户通常由用户持有,用来存储ETH。另一种是合约账户,合约账户下存储着智能合约的代码。重要的是,只有外部账户才能启动交易。

交易

交易是从一个账户发送到另一个账户的消息。消息内容可以是转移ETH。如果目的账户是合约账户,其智能合约代码将被执行。有关智能合约代码执行的每一笔交易将在网络中的所有节点上执行。所有的智能合约代码运行以及交易执行都将被记录在以太坊区块链上。

Solidity

Solidity 是一种面向合约的高级语言,其语法与JavaScript相似。Solidity是静态类型的,支持继承,库以及复杂的用户定义类型。编译后就是节点运行的EVM程序集。

WEB3
先通过简单的将ETH从一个账户发送到另一个账户开始与以太坊互动。因为刚开始,我们可能会弄的一团糟,所以不想用真正的ETH来做这个实验,经过搜索,发现了testrpc,这是一个用于测试和开发的以太坊客户端,是由npm管理的。让我们安装这个客户端并开始使用它:

1
2
npm install -g ethereumjs-testrpc
testrpc

你会注意到testrpc已经产生了10个地址,这些地址都拥有虚拟的ETH可供测试无需担心。有一点是testrpc的状态并不稳定,每次关闭后,节点和账户状态将被清除。

Web3.js 是一个实现了以太坊 JSON RPC 的JavaScript库。我们将使用Web3.js与以太坊节点(在这个例子中是testrpc)进行交互。安装只需运行:

1
npm install -g web3@0.20.1

顺便提一句,在这个例子中,安装 Web3 0.20.x 版本而不是公测1.0.0版本。首先,需要将本地testrpc测试节点连接到Web3.js,为了做到这一点,我们要求Web3 使用localhost provider。让我们打开一个节点控制台并输入以下命令:

1
2
3
Web3 = require('web3')
provider = new Web3.providers.HttpProvider("http://localhost:8545")
web3 = new Web3(provider)

我们正在使用默认的testrpc端口(8545),如果你设置了另一个端口,记得更改provider的URL。当你获得web3 实例后,首先运行以下命令以获得你的以太坊节点中的账户列表及其各自余额:

1
2
3
4
web3.eth.accounts.forEach(account => {
balance = web3.eth.getBalance(account);
console.log(balance);
})

你可能注意到了,输出不全是数字列表,这是因为Web3使用大数对象来处理数字值,而JavaScript无法正确处理大数类型。可以通过这个链接了解更多。

同时,这些余额不是用ETH表示的,实际上它们的单位都是基本单位wei。1ETH是10¹⁸ wei。

回到刚刚的话题,让我们试着在两个账户之间发送ETH。指需输入web3.eth.accounts并选择其中的两个,你可以使用sendTransaction方法:

1
2
3
4
from = web3.eth.accounts[0]
to = web3.eth.accounts[1]
transaction = { from: from, to: to, value: 100000 }
transactionHash = web3.eth.sendTransaction(transaction)

命令输出的是交易哈希,你也可以通过以下命令获得交易信息:

1
web3.eth.getTransaction(transactionHash)

你可能还想检查你使用的账户的余额是否已经更改。你可以使用下面的命令来验证:

1
2
3
4
web3.eth.accounts.forEach(account => {
balance = web3.eth.getBalance(account);
console.log(balance);
})

接下来,我使用HTML和jQuery以及一点Bootstrap搭建了一个简单的UI使得它更美观一点。你可以在repo中看看它。这就是所说的DApp即分布式应用。也就是说,一个部分后端代码运行在分布式点对点网络上的应用程序;在这个例子中,分布式点对点网络是指以太坊网络。

上图是用以测试ETH交易的DApp的UI

你将找到UI的index.html文件以及与以太坊交互的app.js文件,这基本上就是我们前面所描述的用一些jQuery回调来填充UI。可以复制repo并运行起来试一下。

谢谢你阅读这篇博客,如果你有任何问题,意见或者建议欢迎告诉我!如果你喜欢这篇博客,请继续关注本指南的第二部分,我将重点介绍智能合约!

谢谢Manuel Araoz

原文链接: https://blog.zeppelin.solutions/a-gentle-introduction-to-ethereum-programming-part-1-783cc7796094

作者: Facu Spagnuolo

翻译:https://www.bankofcanada.ca/wp-content/uploads/2017/05/fsr-june-2017-chapman.pdf

  • 分布式账本技术(DLT)通常被称为比特币的基础。DLT提供了一种全新方式进行(和跟踪)金融交易。研究人员正在调查其在金融体系的实用性。
  • Jasper项目是基于DLT大额支付系统的技术验证。该验证对DLT作为金融系统基础建设技术的成熟度提供了重要见解。
  • 对于大额支付系统等关键的金融市场基础设施(FMI),目前版本的DLT还无法提供与集中式系统同样的整体能力。然而,与DLT的初始加密货币应用相比,最新版本的DLT已经取得了巨大的进步。
  • 基于DLT的大额支付系统的优势是其可以接入更大的DLT生态市场(可能包括跨境交易)。

什么是分布式账本系统?

比特币在2009年引入分布式账本技术,其后开始流行。比特币是数字货币的代表。交易都记录在账本上,对所有人都是可见的,由分布式的计算机(矿工)维护。这些计算机是系统上的节点,这些节点在创建新交易时更新账本。该账本使用一系列密码学技术记录交易,若干笔交易被封装成块,交易块与块连接在一起,这种账本被称为区块链。
区块链是一个突破,它展示了一种方法来维护各方之间的账本,(i)没有人监督该系统;(ii)交易可以可靠地更新并且记录到比特币系统(无需担心其他成员的诚实度)。

通过让矿工解决数学难题来争取获得验证交易块的权利,从而实现分布式账本的“可靠性”更新。第一个完成一个新的区块广播的矿工为其他矿工提供区块,并以该区块创建的新比特币(矿山)作为回报。虽然挖矿很难,但很容易验证。一旦其他节点看到并验证了这个新矿山,新的区块就被添加到链的后面,块中的交易则被认为是正确的,矿工们开始挖掘其他的新交易。节点对新区块达成一致的方式称为共识机制,比特币的共识机制叫做工作证明(PoW)。

虽然比特币系统已具有相当的弹性,但是他有以下几个不足:

(i)所有交易对每个人都是可见的,但是这是违反银行法的,并使某些参与方利益受损;

(ii)在时间和能源方面,挖矿的代价非常高,在受信任的环境中通常不需要它的好处;

(iii)该系统对任何参加者都是匿名开放的。

为了解决上述问题,人们一直在开发比特币的替代品。新的分布式账本系统只允许受限制的可信对手访问。在一些系统中,共识机制被其他方法所取代。在Jasper阶段2中使用的Corda平台,是通过每个参与方都信任的公证节点完成的,并替换PoW。并且,放弃了区块链的链式结构,并将其替换为分布式账本结构,每个节点只能访问必要的数据,减少系统的透明度,为参与者提供更多隐私**。

Jasper流动资金模型(LSM)利用一个定时多边支付结算的队列,如果银行有非紧急付款,将付款存入队列中。在银行提交付款通知后,提交的付款将与其他排队付款一起等待。定时到达时,该队列暂时被锁定,而算法结合所有提交的付款,确定每个银行的净付款并评其流动性。

支付队列本质上是集中的。关键的问题是如何在DLT系统中实现它,而不是使用传统的集中账本系统。这些技术问题带来了极大的复杂性。

流动资金模型

Jasper项目的创新解决方案是在Corda平台上加入“吸入/呼出”程序。在”匹配”周期开始之前,银行向队列提交付款。这些付款不会立即添加到账本中,而是付款指令加载到队列中,直到”匹配”周期开始。此时,会发生一系列事件。首先,在“吸入”阶段,向参与匹配周期的所有银行发送通知,要求他们向加拿大银行发送数字存托凭证(DDR)。然后验证每一笔付款并添加到账本中。然后,在“呼出”阶段,”匹配”算法确定付款的全部子集,以净额为基础,在具备可用资金的情况下进行清算。加拿大银行将DDR付款返还给所有参与银行,金额等于他们所提供的金额,加上或减去”匹配”算法完成后的金额。

举例说明,假设有两家银行A和B,在队列中支付对方100美元和90美元。此外,作为吸入阶段的一部分,每家银行都将15美元送到队列中。扣除两次付款后,该算法将向A银行收取10美元,并向B银行支付10美元。鉴于他们在吸入阶段的贡献,在呼出阶段A银行为支付5美元,对B银行为支付25美元。

然后验证这些交易并将其添加到账本中。与算法不匹配的付款保留在队列中。此时开始一个新的匹配周期。在下一个匹配周期结束之前,银行可以自由输入或移除队列中的付款。重复该过程。

效率和金融稳定性风险

信用和流动性风险

Jasper平台没有设计信用风险,因为所有的支付都是对中央银行存款的索赔,这是无风险的资产。参与者通过LVTS将现金转入加拿大银行,然后,大额转账系统(LVTS创建DDR,DDR可以在分布式账本平台上交换。总的来说,本设计证明信用上是可兼容的。

Jasper合并了一个模拟现有实时总额结算(RTGS)系统功能的流动资金模型(LSM),以缓解流动性风险,参与者将对不够充足的DDR进行支付。Jasper流动资金模型(LSM)的性能目前正在使用模拟数据进行测试。预测这些模拟结果还为时尚早,但我们可以报告,迄今为止,还没有看到证据表明在分布式账本上实施LSM会改变其相对于中央系统的使用或性能。基于DLT技术的LSM很可能可以做出与现有LSM类似的流动性资金系统。

结算风险

结算定义为资产不可撤销和无条件的转移。

与Jasper方案相关的两个方面:分布式账本更新过程的确定性,和法律确权。

为了确保法律的正当性,Jasper项目的结构如下:

DDR的转让是相当于中央银行存款基础债权的完全(不可撤销)转移。这个设计与DDR的发行有关,因此独立于Jasper平台。

另一方面,为确保方案最终完成,需要解决DLT基础技术相关的问题。在以太坊中,使用PoW共识机制来验证付款。但是PoW是不确定的,付款可能出现失败。在Corda平台中,理论上讲,可信公证人的角色将消除这种不确定性,交易一旦完成就无法撤销。但是,系统还没有经过压力测试,因此一些风险可能仍然与方案有关。

运营风险

总体评估表明,与集中式平台相比,分布式账本如果没有经过精心设计,可能会降低运营弹性。基于Corda,Jasper阶段2在满足金融市场基础设施(PFMI)方面比当前集中式系统更加昂贵。在Jasper阶段2中,参与者需要投资高可用节点以减少停机的可能性。

另一个关键方面是可扩展性。目前,LVTS每天处理32,000笔交易,峰值吞吐量约为每秒10笔交易。在DLT中,”分配”算法消耗了一定的时间。在像以太坊这样的PoW平台上,扩展能力有限。在第一阶段,大概是每秒14笔交易,以太坊是为公有链设计的,速度限制节点之间的信息流。虽然这个速度足以处理当前每日的LVTS,但它限制了未来的高峰量。相比之下,可扩展性不会成为Corda平台的一个限制,因为Corda没有基于固定时间的共识方法,只需要相关方的节点和公证人验证事务。

透明性和隐私

大额支付系统需要参与者保持交易私密性,防止其他参与者窥视这些信息。参与者的客户也需要保持隐私。PoW系统是不适合的,因为所有交易都是公开的。

相比之下,基于公证的DLT系统(如Corda)则允许增加隐私,因为受信任的第三方(例如加拿大银行)有助于验证所有交易。Corda系统缺乏透明性意味着系统中没有任何节点(公证人可能除外)拥有全部信息。如果一个或多个节点的信息被破坏,则可能无法重建整个网络,因为即使公证人也没有全量的账本副本。这就需要对单个节点进行备份。这提出了在交易保持私密的限制下,DLT的运营恢复能力是否有可能的问题。

结论

Jasper项目让我们更好地理解了DLT大额支付系统运营者,参与者和中央银行的角色和责任。在DLT框架中,运营者的角色可能更接近规则制定者或标准制定者的角色,而不是传统的IT基础架构运营商。

此外,Jasper项目促使大额支付系统相关者共同开发平台。私人和公共部门合作,从项目中了解了DLT技术的很多内容。他们发现这降低了相互承认所涉过程的复杂性。

纯粹独立的DLT大额支付系统不太可能与集中式的收益相匹配。因为上面讨论的LSM,与目前的集中式系统相比,增加的复杂性导致进一步的运营风险。

相反,基于DLT的大额支付系统的好处是可以与更广泛的FMI生态系统互动。例如,将其他资产与支付相结合(抵押品质押和资产出售),通过整合后端系统,扩大范围经济并降低参与者的成本。

  1. 编写 solidity 代码,选择 Web3 Provider
  1. Yes
  1. 节点IP地址
  1. 点击 Create,部署代码。查看底部 log 成功与否,这里需要花费几秒钟的时间。成功后 copy 合约地址。
  1. 本地查看调试网页。

示例源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>

<link rel="stylesheet" type="text/css" href="main.css">

<script src="./node_modules/web3/dist/web3.min.js"></script>

</head>
<body>
<div class="container">
<h1>Coursetro Instructor</h1>

<h2 id="instructor"></h2>

<img id="loader" src="https://loading.io/spinners/double-ring/lg.double-ring-spinner.gif">
<label for="name" class="col-lg-2 control-label">Instructor Name</label>
<input id="name" type="text">

<label for="name" class="col-lg-2 control-label">Instructor Age</label>
<input id="age" type="text">
<button id="button">Update Instructor</button>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>

<script>
if (typeof web3 !== 'undefined') {
web3 = new Web3(web3.currentProvider);
} else {
// set the provider you want from Web3.providers
web3 = new Web3(new Web3.providers.HttpProvider("http://47.92.53.158:8545"));
}
web3.eth.defaultAccount = web3.eth.accounts[0];

var CoursetroContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"_fName","type":"string"},{"name":"_age","type":"uint256"}],"name":"setInstructor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getInstructor","outputs":[{"name":"","type":"string"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"name","type":"string"},{"indexed":false,"name":"age","type":"uint256"}],"name":"Instructor","type":"event"}]);

var Coursetro = CoursetroContract.at('0x6f57ae4ea0bb4a6bc3c153ced8202217d63d5fca');
console.log(Coursetro);

var instructorEvent = Coursetro.Instructor();
instructorEvent.watch(function(error, result){
if (!error)
{
$("#loader").hide();
$("#instructor").html(result.args.name + ' (' + result.args.age + ' years old)');
} else {
$("#loader").hide();
console.log(error);
}
});
$("#button").click(function() {
Coursetro.setInstructor($("#name").val(), $("#age").val());
$("#loader").show();
});

</script>

</body>
</html>

ERC stands for “Ethereum Request for Comment” This is Ethereum’s version of a Request for Comments (RFC), a concept devised by the Internet Engineering Task Force. Memos within an RFC contain technical and organizational notes. For ERCs, this includes some technical guidelines for the buildout of the Ethereum network.

This was written by Ethereum developers for the Ethereum community. Thus, the workflow of generating an ERC includes a developer. To create standards for the Ethereum platform, a developer submits an Ethereum Improvement Proposal (EIP). This includes protocol specifications and contract standards. Once that EIP is approved by a committee and finalized, it becomes an ERC. The complete list of EIPs can be found here.

The finalized EIPs give the Ethereum developers a set of implementable standards. This allows Smart Contracts to be built with these standards, which a common interface can access. ERC20 is the most well-known of all the standards within the entire crypto community, and most tokens issued on top of the Ethereum platform use it.

Sources link ==> https://github.com/OpenZeppelin/openzeppelin-contracts

ERC20

任何 ERC20 代币都能立即兼容以太坊钱包(几乎所有支持以太币的钱包,包括Jaxx、MEW、imToken等,也支持 erc20的代币

The ERC20 standard includes the following functions:

1
2
3
4
5
6
7
totalSupply() //returns total token supply
balanceOf(address _owner) //returns account balance of _owner’s account
transfer(address _to, uint256 _value) //takes in number _value and transfers that amount of tokens to address _to and triggers transferevent
transferFrom(address _from, address _to, uint256 _value) //transfers _value amount of tokens from the address _from to the address _to, and triggers the transfer event.拥有者从 _from地址给 _to地址转账授权范围内的一定额度的一类同质化通证。
approve(address _spender, uint256 _value) //allows _spender to withdraw any number up to _value amount
allowance(address _owner, address _spender) //returns the amount which the_spender is still allowed to withdraw from the _owner
// 授权给_spender账户一定额度。拥有者 _owner给消费者_spender在当前查询账户授权(approve)的额度。

The following events are triggered based on the functions above:

1
2
transfer(address indexed _from, address indexed _to, uint256 _value) //this is triggered whenever tokens are transferred
approval(address indexed _owner, address indexed _spender, uint256 _value) //is triggered on any call to approve()

ERC20 was proposed in 2015 and officially formalized in September 2017. It is a great starting point for token standardization. However, some in the developer community have noted that it has certain flaws and vulnerabilities. Additionally, there are some use cases that require something different.

另外,https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC20

Extensions\扩张功能

Utilities\工具方法

ERC223

Status: Open

Date Proposed: 3/5/2017

一句话:ERC223令牌标准可以防止令牌在以太坊网络上丢失。

A post by developer Dexaran describes these two scenarios in detail:

There are two ways of performing a transaction in ERC20 tokens:

  1. transfer function.
  2. approve + transferFrom mechanism.

Token balance is just a variable in the token contract.

The transaction of a token is a change in the internal variables of the contract. The balance of the sender will be decreased and the balance of the recipient will be increased.

The transfer function will not notify the recipient when the transaction occurs. The recipient will not be able to recognize the incoming transaction! I wrote this illustration of the process that is leading to unhandled transactions and money losses.
As a result, if the recipient is a contract, users must transfer their tokens using the approve +transferFrom mechanism. If the recipient is an externally owned account address, users must transfer their tokens via the transfer function. If a user makes a mistake and chooses the wrong function, the token will get stuck inside contract (contract will not recognize a transaction). There will be no way to extract stuck tokens.

His proposed solution to this issue is contained within ERC223. It is very similar to the ERC20 standard, but it solves the problems described above. When tokens are transferred to a smart contract, a special function of that contract is tokenFallback. This allows the receiving contract to decline the tokens or trigger further actions. This can be used in place of the approvefunction in most cases.

由openzeppelin-contracts SafeERC20 完成。

ERC621

Status: Open

Date Proposed: 5/1/2017

一句话:发行 Token 总量可变。ERC621 = ERC20 + increaseSupply() + decreaseSupply()

ERC621 is an extension of the ERC20 token standard. It adds two additional functions, increaseSupply and decreaseSupply. This can increase and decrease the token supply in circulation. ERC20 only allows a single token issuance event. This restricts the supply to a certain amount which can’t be changed. ERC621 proposes that totalSupply can be modified.

ERC721

Status: Open

Date Proposed: 9/22/2017

一句话:每个代币都是 unique,例如以太猫。

ERC721 is very different than ERC20 and ERC223. It describes a non-fungible token. This means that each token is totally different and each one can have a different value to different users. One way to think about this is to recall CryptoKittes. Each one is its own separate commodity whose value is based on its own rarity and desirability by users.

ERC721 tokens can be used in any exchange, but the token value is “a result of the uniqueness and rareness associated with each token.” The standard functions are name, symbol, totalSupply, balanceOf, ownerOf , approve , takeOwnership , transfer , tokenOfOwnerByIndex, and tokenMetadata. It also defines two events: Transfer and Approval. This article by Gerald Nash does a good job explaining the concept of fungibility as it relates to tokens and goes into good technical detail.

ERC1155

Status: Final

Date Proposed: 2018-06-17

一句话:ERC-1155的创造者是Enjin coin的CTO Witek Radomski。ERC1155标准定义了一种解决上述问题的新方法。现在“物品”(可能包含ERC20的token或ERC721的token或两者都有)可以被单一的一个合约(打包处理)来定义了。合约里包含区别token们所需的最小量的数据。

ERC1155协议主要包括ERC1155Mintable.sol同质化可增发智能合约和ERC1155NonFungibleMintable.sol非同质化可增发智能合约,本章只讲解同质化可增发智能合约的功能。