代币合约Token数组增删改查的合约Browsersolidity基于账户的代币合约Token
我们依然打开Browser-solidity的地址:https://ethereum.github.io/browser-solidity
一个简单的实现对数组增删改查的智能合约 function getStrAt(uint n) constant returns (string s){
string tmp = strArr[n];
return tmp;
} function updateStrAt(uint n, string str) {
strArr[n] = str;
} function deleteStrAt(uint index) {
uint len = strArr.length;
if (index >= len) return;
for (uint i = index; i<len-1; i++) {
strArr[i] = strArr[i+1];
}pragma solidity 0.4.9;
/*数组类型Demo*/
contract DemoTypes303 {
/*String数组例子*/
string[] strArr;
function add(string str){
strArr.push(str);
}
delete strArr[len-1];
strArr.length--;
}
}
string[] strArr;
定义了一个字符串的数组变量strArr, 且该变量没有public因此不可见strArr.push(str);
其中的push是数组类型的两个member之一,另一个是length. 这里的push就是给该数组增加一个元素。//这里实现了对数组的新增功能function add(string str){ strArr.push(str); }
getStrAt(uint n)
是一个简单的读取字符串的函数,//这里实现对数组的读取功能updateStrAt(uint n, string str)
// 实现对数组的更新功能deleteStrAt(uint index)
这个值得一说,因为solidity默认的数组类型中没有删除功能,因此此处自己写了一个删除代码,核心方法就是保证删除某项后,后面的元素依次向前,同时删除数据,同时保证数组的member length正确。


- 输入
hello 01
, 然后点击add按钮,我们可以看到在经过一部分gas的消耗后,该数据被执行成功! - PS:需要注意的是这里的getStrAt和add,update,delete等方法颜色不同,按上方的分类,一个是transaction,一个则是call,因此在geth上的调用方法也是不同的。
strArr
的数值了,根据数组常识,我们只增加了一个元素,因此getStrAt[0]
应该为hello 01
. 而getStrAt[1]
则应该为错误。实际结果如下:getStrAt[0]
getStrAt[1]:

- step 1需要先add(“hello 01”), add(“hello 02”),add(“hello 03”)
- step 2然后调用deleteStrAt(0);
- step 3 检查是否第一项被删除,而getStrAt(0)应该等于”hello 02″, getStrAt(1)应该等于”hello 03″
- 然后重复step1-3,作用于deleteStrAt(1),删除中间项目,或者deleteStrAt(2)删除最后一项,还有deleteStrAt(3)/deleteStrAt(100)/deleteStrAt(-100) 等检查是否做了边界检查。
contract DemoTypes {
/*uint public resultOfF;*/
event LogUint(uint value);
event LogInt (int value); function f(uint a) returns (uint b)
{
uint result = a * 8;
/*resultOfF = result; //debug used only;*/
LogUint(result);
return result;
} /*输入长度宽度,返回面积*/
function f2(int width, int height) returns (int square) {
if (width < 0 || height < 0) throw;
int result = width * height;
LogInt(result);
return result;
} /*输入N,计算N的阶乘,循环实现*/
function f3(uint n) returns (uint jiecheng) {
if (n == 0) throw; uint result = 1;
for (uint i=1; i<=n; i++) {
result *= i;
}
return result;
}pragma solidity ^0.4.4;
/*计算从1到N的求和*/
function f4(uint n) returns (uint sum) {
if (n == 0) throw; uint result = 0;
for (uint i=0; i<=n; i++) {
result +=i;
}
return result;
}
}
pragma solidity 0.4.9;
contract Token {
function Token() {
}
}
function Token() {}
是该contract
的构造函数。该合约在browser-solidity上可以执行成功,这里就不演示了。我们给这个Token代币合约添加一个数字数组,并赋予一个初值。pragma solidity 0.4.9;
contract Token2 {
uint[] public balancesOf;
function Token() {
balancesOf.push(100);
balancesOf.push(200);
}
}
public
的变量balancesOf
, 然后在构造阶段,就给这个变量添加两个初始值。100
&200
用户先点击Token这个构造函数,然后再输入0和1,然后点击balancesOf 可以分别看到两个数值。
pragma solidity 0.4.9;
contract Token3 {
uint[] public balancesOf;
function Token() {
balancesOf.push(100);
balancesOf.push(200);
}
function transfer(uint _from, uint _to, uint _amount) {
balancesOf[_from] -= _amount;
balancesOf[_to] += _amount;
}
}
_amount
从_from
转移到_to
;该功能在browser solidity调试成功,如下图所示:
contract Token4 {
uint[] public balancesOf;
function Token() {
balancesOf.push(100);
balancesOf.push(200);
} function transfer(uint _from, uint _to, uint _amount) {
balancesOf[_from] -= _amount;
balancesOf[_to] += _amount;
}pragma solidity 0.4.9;
function mint(uint value) {
balancesOf[0] += value;
}
}
mint()
我们就可以随意的给balancesOf[0] 增加代币了。该代码有兴趣的同学,请在browser-solidity上实验。注意以上代码只用于学习使用,很多场景还未考虑,例如transfer中没有考虑_amount>当前账户余额的场景。不可用于商业化应用。本文初步介绍了Token的核心功能,包括构造,挖矿、转账等。但是,我们知道以太坊的核心是账户体系和智能合约,真正有意义的是在各个账户之间可以流通的代币合约。有了这些代币,我们才能用于众筹、众包等各种商业应用的实现。下篇将介绍一个包含账户的代币合约------------------------------------------------------------------------------------------------------------------------------基于账户地址的Token合约pragma solidity 0.4.9;
contract Token {
mapping (address => uint) public balancesOf;
function Token() {
balancesOf[msg.sender] = 10000;
}
}
mapping
关键词的定义
Mapping types are declared as mapping(_KeyType => _ValueType). Here _KeyType can be almost any type except for a mapping, a dynamically sized array, a contract, an enum and a struct. _ValueType can actually be any type, including mappings.Mappings can be seen as hashtables which are virtually initialized such that every possible key exists and is mapped to a value whose byte-representation is all zeros: a type’s default value. 引用自here
address
的定义:address: Holds a 20 byte value (size of an Ethereum address). Address types also have members and serve as base for all contracts. members of addresses:这里的address简单地说就是geth中的账户的地址(公钥) 因此此处的代码balance
andsend
引用自here
mapping (address => uint) balancesOf
代表定义了一个 key为address类型, value为uint类型的hashtable,名字为balancesOf
.所以任何在区块链私链上的账户都可以通过balancesOf[address]
来查询他们的代币数量。
msg
的定义msg就是指谁调用该智能合约时候发来的信息,之前说过智能合约也是一个账户。因此在以太坊中调用智能合约从底层看来就是一个账户给智能合约账户发送了一个transaction,里面包含了谁发送的,发送了多少以太币,发送了多少gas 下面是msg的一些变量msg.data (bytes): complete calldata msg.gas (uint): remaining gasmsg.sender (address): sender of the message (current call)msg.sig (bytes4): first four bytes of the calldata (i.e. function identifier)msg.value (uint): number of wei sent with the message引用自here最主要的就是msg.sender,代表那个账户调用该智能合约。msg.value
- 因此
balancesOf[msg.sender] = 10000;
代表给msg.sender也就是创建该合约的地址赋予一个初始值 10000;
function transfer(address _to, uint _value) {
if (balancesOf[msg.sender] < _value) throw; //避免转移出去的代币超过当前的存货
if (balancesOf[_to] + _value < balancesOf[_to]) throw; //避免自己调用自己,或者递归调用
balancesOf[msg.sender] -= _value;
balancesOf[_to] += _value;
}pragma solidity 0.4.9;
contract Token {
mapping (address => uint) public balancesOf;
address public owner;
function Token() {
owner = msg.sender;
balancesOf[msg.sender] = 10000;
}
function mint(uint _amount) {
balancesOf[owner] += _amount;
}
}
- 在上面的代码中,我们设置一个public owner, 保存下创建合约的msg.sender, 记录下创建者的地址。
- 在
function transfer()
中,我们设置了两个条件,避免转移出去的代币超过存货的情况,以及自己转移给自己的问题。 - 在
function mint()
中,我们给合约的owner增加我们定义的代币。从而让其方便的分给别人。

- 我们在代码中将
owner = msg.sender
,因此owner就是创建合约的地址。我们可以看到balancesOf[owner]
的数据为10000,和代码相同。

- 调用方法
mint(500)
,自动给balancesOf[owner] += 500;
查看存额从10000增加到10500.

- 调用方法
transfer("0xccccc",300)
, 可以看到owner的存额减少300,balancesOf[“0xccccc”]增加300.

本文链接:https://www.8btc.com/article/122337
转载请注明文章出处