
Overall
0
Activity
Funds Held
Trading Pairs
0
Registered Location
-
Followers
0
为了了解什么是智能合约以及它们如何发挥作用,退后几步来研究与区块链相关的其他一些概念(也称为分布式分类账技术)会很有帮助。
区块链和加密货币的简短历史
2009年,比特币风靡全球,成为第一个已建立的去中心化电子货币,通过消除了对金融机构私人记录的依赖,从而提高了透明度,可用性和责任感,从而将钱币带入了数字时代。准确的帐户余额和交易分类帐。
比特币之所以具有革命性,是因为它引入了一种让同network网络在共享的,公开的货币交易记录上达成共识的系统,从根本上确定了谁拥有多少钱。在该系统中,用户广播交易,矿工池随后将竞争这些交易以收集并保护到公共区块链的下一个区块中。这使用户可以发送和接收资金并保留这些交易的日志,而无需将控制权交给中央银行或金融机构来代表他们执行这些操作。与政府发行的法定货币相比,使用分散式加密货币具有许多优势,但是其中突出的优势是更快的结算速度和更低的费用。
尽管使用美元等法定货币进行的交易可以通过电子方式快速启动,但这些交易在幕后的实际转移和结算可能需要几天或几周才能完成。负责结算交易的中间实体在整个过程中也采取了削减措施,通常采取向零售商收取的费用的形式,这些费用随着消费者价格的上涨而上涨。当然,这些中介人的撤离也导致规避了交易费用。对于像比特币这样的加密货币,采矿费用由交易发起者支付,并由矿工接受,矿工负责确认交易区块并将其添加到区块链中。这些交易仅需几分钟即可解决,与传统的交易费用相比,相关的采矿费用通常较低。
2015年,以太坊作为运行图灵完备的编程语言的基于区块链的去中心化虚拟机发布。
比特币利用其区块链维护交易历史的全球分类帐,而以太坊则利用其区块链维护通用的全球状态转换系统。在该系统中,用户不仅可以维护账户余额和交易的分类账,还可以在区块链上记录能够被调用时执行任意代码的计算机程序。这样就可以以对所有相关方透明的方式来编纂和自动化价值分配。这些计算机程序或智能合约可以促进资产从一个帐户到另一帐户的简单转移,管理所有权,例如域名注册机构或专利,权力预测市场或记录选举结果。使用智能合约,您可以创建代表非流动资产的代币,并与他人自由交易。
例如,NBA控卫后卫斯潘塞·丁威迪(Spencer Dinwiddie)在2019年9月宣布了他打算对他的续约进行代币化的意图,向投资者出售代表他未来赚钱潜力的数字代币以立即获得回报。购买这些代币将使投资者有权获得他的薪水加利息。他是否能够绕开NBA规定来实际执行该计划还有待观察。
所有这些都将我们带到今天的职位,我们将研究一个去中心化应用程序或dapp的简单示例,您将自己在本地计算机上实现它。
Dapps是使用JavaScript,HTML和CSS等语言编写的应用程序,它们利用后端的智能合约来显示和更改信息。它们是从集中式Web2架构到分散式Web3架构的重要组成部分。
这篇文章将指导您完成编写智能合约的工作,以Solidity(一种用于编写以太坊智能合约的最流行的语言)对不可替代的代币合约进行编程。然后,我们将使用一个简单的React应用程序连接到该智能合约。
您今天将要实现的dapp只是流行的CryptoKitties收藏dapp的一小部分。
开发设置
确保已安装并设置Node , Git和Metamask 。 Metamask是一个扩展,允许您连接到以太坊dapp并与之交互。
导航到该GitHub存储库,以克隆您开始本研讨会所需的代码。
$ git clone https://github.com/jp3hou/dapp-demo
$ cd dapp-demo
克隆存储库后,在文本编辑器中打开项目,然后导航到“ contracts / KatCoin.sol”文件。
以太坊基础知识
以太币是以太坊生态系统中用来支付交易费用的货币。
以太坊通过账户跟踪状态,账户可以是外部拥有的账户也可以是合约账户。外部拥有的帐户属于用户,并由私钥控制,而合同帐户则由其合同代码控制。
每个帐户都有一个20字节的地址,并包含四个字段:
- 随机数,确保交易仅处理一次的计数器
- 以太平衡
- 存储空间
- 合同代码(如果这是一个合同帐户)
从一种状态到另一种状态的转换是通过交易进行的,其中包括发送方,接收方,从发送方转移到接收方的以太量以及此交易的气体限制。
“气体”用于跟踪使用了多少计算能力。通过要求用户为所消耗的每种资源付费并在智能合约达到分配的气体限制后取消功能,从而防止了DoS攻击。
一些扎实的基础知识
Solidity是用于以太坊智能合约开发的最流行的语言。它是:
- 静态类型
- 面向对象
- 在部署到区块链之前被编译为EVM字节码
空的KatCoin模板
语用强度^ 0.4.24;
导入'./Ownable.sol';
合约KatCoin拥有{
事件Minted(地址所有者,uint256 katId,uint256基因);
事件已发送(地址从,地址到,uint256 katId);
struct Kat {
uint32颜色;
uint16代;
}
凯特[] kats;
映射(uint256 =>地址)private _katOwner;
映射(address => uint256)private _ownedKatsCount;
构造函数()公共{
对于(uint32 i = 0; i <30; i ++){
kats.push(Kat((i + 3)* 32,0));
_mint(address(this),kats.length-1,i * 32);
}
}
函数balanceOf(地址所有者)公共视图返回(uint256){
//填满我
}
函数ownerOf(uint256 katId)公共视图返回(地址){
//填满我
}
函数getKat(uint256 katId)公共视图返回(
uint32颜色,
uint16世代
){
//填满我
}
函数购买(uint256 katId)公共应付款项{
//填满我
}
函数_transferFrom(地址从,地址到,uint256 katId)内部{
//填满我
}
函数_mint(
写给,
uint256 katId,
uint256基因
)内部{
//填满我
}
函数_addKatTo(地址,uint256 katId)内部{
//填满我
}
函数_removeKatFrom(地址,uint256 katId)内部{
//填满我
}
}
您会在此文件中看到,我们是从同一目录中的Ownable合同派生KatCoin合同的,该合同定义了KatCoin继承的一些基本身份验证控制和用户权限功能。智能合约为用户提供了从头开始重新构想当前应用程序和系统架构的机会,同时考虑了用户数据和隐私。
注意事项:
- 文件开头的“ pragma”调用定义了要使用的Solidity编译器版本
- 可以定义事件并引发/捕获事件。这对于调试或记录日志很有用
- 我们正在定义私有状态变量,以跟踪哪个地址拥有哪个KatCoin以及一个地址拥有多少KatCoin。 “专用”标识确保仅当前智能合约可访问这些变量,而其任何后代均不可访问
- 构造函数将在初始化此合约时铸造30个KatCoins,并将每个令牌的所有者分配给智能合约本身
填写balanceOf和ownerOf函数
函数balanceOf(地址所有者)公共视图返回(uint256){
require(owner!= address(0));
return _ownedKatsCount [owner];
}
函数ownerOf(uint256 katId)公共视图返回(地址){
地址所有者= _katOwner [katId];
require(owner!= address(0));
归还所有者;
}
注意事项:
- “ require”是内置的Solidity函数,如果给定条件返回false,则该函数会引发异常
- 公共功能是合同接口的一部分,可以从合同内部调用,也可以从其他合同/地址外部调用
- 查看功能是只读功能,这意味着它们不会修改智能合约的状态
填写getKat函数
函数getKat(uint256 katId)公共视图返回(
uint32颜色,
uint16世代
){
Kat存储量kat = kats [katId];颜色= kat.color;
世代=千世代;
}
注意事项:
- 将结构类型分配给具有数据位置“存储”的局部变量,该变量存储对结构的引用
填写_addKatTo和_removeKatFrom函数
函数_addKatTo(地址,uint256 katId)内部{
require(_katOwner [katId] ==地址(0));
_katOwner [katId] = to;
_ownedKatsCount [to] ++;
}
函数_removeKatFrom(地址,uint256 katId)内部{
require(ownerOf(katId)== from);
_ownedKatsCount [from]-;
_katOwner [katId] =地址(0);
}
注意事项:
- 内部功能只能由当前合同及其后代访问
- _addKatTo将其分配给所有者之前,验证KatCoin当前不属于任何人
- _removeKatFrom验证KatCoin的所有者是唯一可以转让所有权的人
- 这些函数更改合同状态变量以反映这些KatCoins的更新所有权
填写_mint函数
函数_mint(uint256 katId,uint256基因的地址)内部{
要求(到!=地址(0));
_addKatTo(to,katId);
发射Minted(to,katId,genes);
}
注意事项:
- _mint验证将令牌分配给有效地址
- 该功能利用我们先前实现的内部功能将该KatCoin的所有权分配给给定地址
- 发出“铸造”事件
填写_transferFrom函数
函数_transferFrom(
地址,
写给,
uint256 katId
)
内部{
require(from == _katOwner [katId]);
要求(到!=地址(0)); _removeKatFrom(from,katId);
_addKatTo(to,katId);发出Sent(from,to,katId);
}
注意事项:
- _transferFrom验证正确的令牌所有权和有效地址
- 利用我们先前实现的内部_removeKatFrom和_addKatTo函数将所有权从给定的“从”地址重新分配给“至”地址
- 发出“已发送”事件
填写购买功能
函数购买(uint256 katId)公共应付款项{
require(katId> = 0 && katId <30);
require(address(this)== _katOwner [katId]);
_transferFrom(address(this),msg.sender,katId);
owner.transfer(msg.value);
}
注意事项:
- 验证令牌是在构造函数中初始化的30个令牌之一
- 验证智能合约是要购买的代币的当前所有者
- “ payable”修饰符表示此功能可以接收以太币
- 利用我们先前实现的_transferFrom函数来更改此令牌的所有权
- 将发送给函数的消息的价值记入所有者
是时候编译和部署了!
打开一个终端窗口,然后运行以下命令:
$ npm运行区块链
这将在您的计算机上启动一个在端口8545上运行的本地区块链服务器。请确保注意输出,因为它将启动一组测试帐户,每个帐户都带有100个测试以太币,供您使用。
复制输出中提供的私钥之一,打开您的Metamask扩展,选择“导入帐户”选项并粘贴该私钥,以便导入该帐户以与您的dapp进行交互。确保已选择要连接的本地网络(Localhost 8545),而不是以太坊主网。
接下来,打开一个新的终端窗口并运行:
$ npm运行迁移
这会将您的代码编译为以太坊虚拟机(EVM)字节码,并将智能合约部署到您的区块链服务器上。
请注意此命令的输出,它将告诉您消耗了多少以太坊,这是将这些合同部署到区块链服务器上的汽油费的一部分,以及KatCoin智能合约的合同地址是什么。
使用从上一步复制的合同地址,在项目中打开“ src / App.js”文件,并用包含该地址值的字符串替换“ CONTRACT ADDRESS GOES HERE”的注释。最终结果应如下所示:
constructor(){
超();
const Kats = window.web3.eth.contract(KatCoin.abi); this.state = {
主题:kats.at(“ 0x8d37b292DE9c41c7A9969461718b1cA8008F421f”),
加载:是的,
猫: []
};
}
运行前端!
在您的终端中,运行:
$ npm运行开始
这将在http:// localhost:3000上启动您的react应用。您应该看到智能合约铸造的30个KatCoins,包括其ID和所有者地址。
单击其中之一的KatCoins尝试购买(应该尝试将其从智能合约转移到您的Metamask钱包中的帐户),然后您应该在Metamask扩展程序中看到一个弹出窗口,要求对此购买交易进行确认。
确认此交易以完成您的KatCoin购买!
恭喜你!现在,您应该看到所有者地址已从智能合约更改为您的帐户,并且应该能够在Metamask中查看您的交易历史记录。
一些安全问题
请记住,智能合约处理的是现实世界中的价值货币,这可能会使用户资金面临风险。智能合约中的错误实际上将使您付出代价。
一旦部署到区块链,智能合约就不会改变。但是,您可以根据需要事先在其中编程自毁功能。请查看CryptoFin的安全审核清单 ,以获取要遵循的一些准则的示例。
这就是演示的全部内容!这只是一个精心设计的示例,向您介绍了在Ethereum上构建dapp的开发工具,但是,既然您已经了解了此介绍,则还有很多其他资源可供您学习。
其他参考
《智能合约简介》最初发表于The Coinbase Blog on Medium,人们通过突出并回应这个故事来继续对话。