以太坊 (五)编写智能合约-建立简易加密代币

本篇文章,我们将写一个简易的加密代币的智能合约来给大家诠释加密代币的原理

启动 ganache-cli

打开终端,启动ganache-cli,相关环境在区块链学习日记(四)这篇文章里面已经有具体说明。

wangsanjundeMacBook-Pro:~ wangsanjun$ ganache-cli
Ganache CLI v6.0.3 (ganache-core: 2.0.2)

Available Accounts
==================
(0) 0x79221bc486bcc9380d280c4221856f7122b32d6f
(1) 0xc72f1267309aaa7aa79c1f6b971edca111e0c3e4
(2) 0x5139a3ca66f06102eabbb38989021bca9ade63db
(3) 0x20cb6137afeb2da01d2fb28ade7822a5ffe214e1
(4) 0x93382d64508ca98b9f2a7dbf13366be157be04fa
(5) 0x051a305c1d016391cea8d9d19c5560d0bb4148f4
(6) 0x9676763004ec23beab44feeb6d9d9f86a846b7ab
(7) 0xe0400ae3a7390d78397d12fc0b768f8209f5abf4
(8) 0xd17a5a1a9b26d35ef957bf5686db90b011f8d9a8
(9) 0x0b529a02f4f6c997dae911a64fce47d4a850b77c

Private Keys
==================
(0) 85e35b54c141ebe2df61cc56192aced3ba03f51e2ae8ca0ed299a25ab8ac7155
(1) 4215839182c1ffcb5f8854631fd1a2372be3b3910a0f193e392f90df85befb03
(2) 90081b0b6f3ffc6ce6245bed5f0f864982522d65a4b47a891f07b6be0deec03b
(3) 845efda127b31c0c0e4ef142bb62de73dc89bf3269d1ace9e3be3ad2476c29ff
(4) dfa540af69e16a81415e362295e9526acb4189eb883bbf30a843c2289a2f7cb0
(5) 18fac89e76063d582881ad98a6ad6f79e07782b64bbac507034ccb5a66cc5e7e
(6) 3e0ab00795f1f061f7ca681e64d51bd1ee59427bfe5477e751ee93f9596d95b6
(7) a09f85a55ee46a61030b87bea045cff8e43671287709608bd329f41e33660442
(8) 420ec6889ba6aa5ec1cfd1757b9209687350487cc14dc56e8792b2bd6727de4a
(9) 45e96bbd340ef850ee32b1f3a5808ed3aecad889f1929377fe6eabd95c0dcc77

HD Wallet
==================
Mnemonic:      neither mountain become final nephew drill ramp onion attract parade neck merge
Base HD Path:  m/44'/60'/0'/0/{account_index}

Listening on localhost:8545
...

接下来我们就可以一步步的创建我们的加密代币项目了。

代币合约的基本概念

代币合约扮演的角色相当于银行的角色。使用者在代币合约中,用自己的以太币帐户地址当作银行帐户,可以透过代币合约执行转账(transfer,将代币由一个帐户转到另一个帐户),查询余额(balanceOf,查询指定帐户中拥有的代币)等原本由银行负责的工作。因为合约部署在公开区块链上,所有的交易都是公开透明,可供检验的。

创建代币合约项目

wangsanjundeMacBook-Pro:SmartContractDemo wangsanjun$ mkdir EncrptedToken
wangsanjundeMacBook-Pro:EncrptedToken wangsanjun$ truffle init
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!

Commands:

  Compile:        truffle compile
  Migrate:        truffle migrate
  Test contracts: truffle test
wangsanjundeMacBook-Pro:EncrptedToken wangsanjun$ 

新建代币合约

终端执行truffle create contract EncryptedToken命令创建EncryptedToken.sol合约。

EncryptedToken.sol.png

编写合约代码

将下面的合约代码拷贝,替换EncryptedToken.sol文件的代码。

pragma solidity ^0.4.17;

contract EncryptedToken {
  uint256 INITIAL_SUPPLY = 666666;
  mapping(address => uint256) balances;
  function EncryptedToken() {
    balances[msg.sender] = INITIAL_SUPPLY;
  }
  // 转账到一个指定的地址
  function transfer(address _to, uint256 _amount) {
    assert(balances[msg.sender] >= _amount);
    balances[msg.sender] -= _amount;
    balances[_to] += _amount;
  }
  // 查看指定地址的余额
  function balanceOf(address _owner) constant returns (uint256) {
    return balances[_owner];
  }
}

pragma solidity ^0.4.17中的0.4.17代表solidity的版本,^代表0.4.17 ~ 0.4.99之间的solidity都可以正常编译当前版本的合约。

contract相当于其他语言中的classEncryptedToken相当于的名字。contract EncryptedToken可以理解为class EncryptedToken extends Contract

uint256 INITIAL_SUPPLY = 666666声明了一个变量INITIAL_SUPPLY,初始化存储了一个666666的整数作为部署当前合约的钱包地址的代币数。

mapping(address => uint256) balances;balances是一个key类型为addressvalue类型为uint256的键值对 (mapping),相当于 Java 中的map、iOS 中的NSDictionary

function EncryptedToken()函数是EncryptedToken合约的构造函数 (contructor),当EncryptedToken合约调用时,会先执行它的构造函数。

在构造函数中,会以当前部署合约的钱包地址为key,以INITIAL_SUPPLYvalue初始化一个键值对。

function transfer(address _to, uint256 _amount) {
    assert(balances[msg.sender] >= _amount);
    balances[msg.sender] -= _amount;
    balances[_to] += _amount;
}

transfer函数是声明用来从转账到指定钱包地址的函数,_to代表转账的目的地地址,_amount代表转账金额。

assert(balances[msg.sender] >= _amount),这句代码中,我声明了一个断言,当balances[msg.sender] >= _amount,即当前钱包余额小于要转账的额度时,就会抛出异常。

balances[msg.sender] -= _amount;从当前钱包额度中减去_amount

balances[_to] += _amount;,将目标地址的额度增加_amount

 function balanceOf(address _owner) constant returns (uint256) {

    return balances[_owner];
 }

balanceOf(address _owner)函数是用来查询指定钱包地址的余额,_owner即是指定的钱包地址,returns (uint256)代表返回值的类型为uint256constant关键字的作用是,当我们调用balanceOf函数时,它会自动调用call()方法,表明是只读数据,而不需要往区块链写入数据,调用这个方法,不需要花费手续费。

编译与部署

migrations/目录下创建一个名字叫做2_deploy_contract.js的文件。文件中的内容为:

var EncryptedToken = artifacts.require('./EncryptedToken.sol');

module.exports = function(deployer) {
  deployer.deploy(EncryptedToken);
}
2_deploy_contract.js.png

修改truffle.js文件,连接本地ganache-cli环境

module.exports = {
  networks: {
    development: {
      host: "127.0.0.1",
      port: 8545,
      network_id: "*" // Match any network id
    }
  }
};

truffle.js.png

接下来执行compilemigrate命令:

wangsanjundeMacBook-Pro:EncrptedToken wangsanjun$ truffle compile
Compiling ./contracts/EncryptedToken.sol...
Compiling ./contracts/Migrations.sol...

Compilation warnings encountered:

/Users/wangsanjun/Desktop/SmartContractDemo/EncrptedToken/contracts/EncryptedToken.sol:6:3: Warning: No visibility specified. Defaulting to "public".
  function EncryptedToken() {
  ^
Spanning multiple lines.
,/Users/wangsanjun/Desktop/SmartContractDemo/EncrptedToken/contracts/EncryptedToken.sol:10:3: Warning: No visibility specified. Defaulting to "public".
  function transfer(address _to, uint256 _amount) {
  ^
Spanning multiple lines.
,/Users/wangsanjun/Desktop/SmartContractDemo/EncrptedToken/contracts/EncryptedToken.sol:16:3: Warning: No visibility specified. Defaulting to "public".
  function balanceOf(address _owner) constant returns (uint256) {
  ^
Spanning multiple lines.

Writing artifacts to ./build/contracts

wangsanjundeMacBook-Pro:EncrptedToken wangsanjun$ truffle migrate
Using network 'development'.

Running migration: 1_initial_migration.js
  Deploying Migrations...
  ... 0xc4e64f8636e83fe67a9c0044667cf19237e631e801dd682f7ef01c8175eb7d6c
  Migrations: 0x252a66c521dd81312455411acdd8074c159ee300
Saving successful migration to network...
  ... 0x0c2c60f492f7a82ab7d72e523b75f024ae83f402be313d033078d46b49555a89
Saving artifacts...
Running migration: 2_deploy_contract.js
  Deploying EncryptedToken...
  ... 0x14675402f0781db21afccb69a11a3e2177d06d7eba4a95b67a1b146caf48262e
  EncryptedToken: 0x5c6d0f9528791e07350e00e80e66e655583d7b69
Saving successful migration to network...
  ... 0x447a94584192424ff4401892c5f478db7d39218895e856636e578ed536e838e1
Saving artifacts...
wangsanjundeMacBook-Pro:EncrptedToken wangsanjun$  

如上所示,我们已经将EncryptedToken代币合约部署到了ganache-cli上。

合约验证

合约部署完成后,我们通过truffle console开启console控制台,在这个控制台中对已经部署的合约进行验证。

接下来声明一个合约变量存储EncryptedToken合约实例。

truffle(development)> let contract;
undefined
truffle(development)> EncryptedToken.deployed().then(instance => contract = instance)
.....
truffle(development)> 

验证web3.eth.coinbaseweb3.eth.accounts[1]中的余额。

truffle(development)> contract.balanceOf(web3.eth.coinbase)
{ [String: '666666'] s: 1, e: 5, c: [ 666666 ] }
truffle(development)> contract.balanceOf(web3.eth.accounts[1])
{ [String: '0'] s: 1, e: 0, c: [ 0 ] }
truffle(development)> 

经验证,第 0 个钱包地址中的代币余额为666666,第 1 个钱包地址中的代币余额为0

下一步,我们将从第 0 个账号中向第 1 个账号转账666个代币。

truffle(development)> contract.transfer(web3.eth.accounts[1],666)
{ tx: '0x50c71bd9a522afb9ff054bf11755d7665d7d9770f1bfca3548973df7aace24ab',
  receipt: 
   { transactionHash: '0x50c71bd9a522afb9ff054bf11755d7665d7d9770f1bfca3548973df7aace24ab',
     transactionIndex: 0,
     blockHash: '0x2fc452564dad406210c26be62e44770c6fa6ec1f435ff488ffb393a5317b8de6',
     blockNumber: 28,
     gasUsed: 49120,
     cumulativeGasUsed: 49120,
     contractAddress: null,
     logs: [],
     status: 1 },
  logs: [] }
truffle(development)> contract.balanceOf(web3.eth.coinbase)
{ [String: '666000'] s: 1, e: 5, c: [ 666000 ] }
truffle(development)> contract.balanceOf(web3.eth.accounts[1])
{ [String: '666'] s: 1, e: 2, c: [ 666 ] }
truffle(development)> 

如上所示,代币转账成功。

备注:如果合约部署成功之后,又修改了代码。重新编译时,一定要先将build文件夹删除,其次在部署合约时,一定要添加--reset,否则修改后的合约没法部署成功。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容