第二个智能合约
第一个被helloworld占掉了,所以这个是第二个, 通过智能合约实现几个简单的函数,作为对solidity的初步学习
什么是智能合约
solidity官方doc
pragma solidity ^0.4.4;
contract SimpleStorage {
uint storedData;
function set(uint x) {
storedData = x;
}
function get() constant returns (uint) {
return storedData;
}
}
从Solidity角度来看,合约就是存在于以太坊区块链中的一个特定地址中的代码和数据集合。uint storedData 声明了一个类型为 uint(256位的无符号整型)的变量,变量名称为 storedData。你可以把它想象为数据库中的一个字段,该字段是可以被数据库中的方法进行查询,修改。在以太坊中,这个字段是属于一个合约字段。在这个例子中,该变量可以通过提供的get,set方法进行获取或是修改。在Solidity中,访问一个变量是不需要通过this来引用的。
这个合约很简单,只是允许以太坊上的任何人来存储一个数据到某个节点,同时把这个操作发布到以太坊中,当然,以太坊上的其他节点同样可以通过调用set方法来修改你已经存储好的值。虽然有被修改,但是对该值操作的任何历史记录都是保存在以太坊中的。不用担心你的存储记录或是修改记录会丢失。后面我们会将到如何对合约进行限制,只允许你一个人修改这个数据
以上内容引用自shaotine
合约结构
示例代码
使用上面的示例代码 (学习好习惯,以后的tab 就是两个space 了,怕引起圣战…)
代码说明
版本号
pragma solidity ^0.4.4;
第一行表明目前使用的solidity版本,不同版本的solidity可能会编译出不同的bytecode。^代表兼容solidity 0.4.4~0.4.9的版本。
合约类名
contract HelloWorld { ... }
contract是solidity里的一个关键字, 相当于其他的语言中的一个特定的class。因为solidity是专为智能合约(Contract)设计的语言,声明contract后即内置了开发智能合约所需的功能。
合约函数
function sayHello([_in type var]) returns ([tpye]) { return ("Hello World"); //这里是返回string }
solidity是函数式编程语言(类似js),但如果有传入的参数或回传值,需要指定参数或回传值的类型(type)。
到这基本合约结构说完了,试着先写一个
第二个合约
编写
照着上面的模板,试着写了自己的一个 test的合约
pragma solidity ^0.4.17;
contract TestContract {
uint num ;
address owner; // address 是 sd 里面的一种特有的类
modifier onlyOwner() { // modifier 正如其字面意思修饰, 这个关键字用于对固有函数的 重写(后面系统学习)
if (msg.sender == owner) //msg是contract的固有成员, sender ,就是合约的发送者的地址
_;
}
// 设置数
function setNum(uint x) {
num = x;
}
// 得到数
function getNum() returns(uint) {
return num;
}
// 加 这里pure 关键字很重要,个人理解和static 一样, 是个静态方法, 不能使用成员
function addNum(uint a, uint b) public pure returns(uint r) {
r = a + b;
}
//say
function say() public pure returns (string) {
return "Hello";
}
//print name
function print(string name) public pure returns (string) {
return name;
}
}
部署
之前有写到
编译
truffle compile --reset Compiling ./contracts/TestContract.sol... Writing artifacts to ./build/contracts
完成新的合约的重新编译
部署(迁移)
truffle migrate --reset Using network 'development'. Running migration: 1_initial_migration.js Deploying Migrations... ... 0x714a27d42f8ae364616544905182a3f5b7dbf389db49d20863d94e2739271c91 Migrations: 0x909ae0c719f6f424b405683d721e4ff8254314da Deploying TestContract... ... 0xadeaec3e75f3cb3e8f70e4c1b1bca599fd7acd95bbae183ff9a513c5e7d4fa07 TestContract: 0x7db773d54c25e251a6c088a3b8acf783a8a6705d Saving successful migration to network... ... 0x9984265ec8aa5065453013b0df3e6223f35fab384b3919107a503f66798e4a01 Saving artifacts...
在testrpc 端会显示
Transaction: 0x9984265ec8aa5065453013b0df3e6223f35fab384b3919107a503f66798e4a01 Gas usage: 41981 Block Number: 5 Block Time: Thu Jan 25 2018 17:52:15 GMT+0800 (CST)
表示我们的合约已经被挖到(区块确认) 新合约的部署完毕
合约交互
先进入rpc的终端
truffle console truffle(development)> var TestContract truffle(development)> TestContract.deployed().then(instance => contract = instance) // 这里部署合约, 并使用变量保存期返回的句柄
下面是合约函数测试
truffle(development)> contract.say() 'Hello' truffle(development)> contract.addNum(12,12) BigNumber { s: 1, e: 1, c: [ 24 ] } truffle(development)> contract.print("test") 'test' truffle(development)>
可见,可以正常使用合约函数, 至此第二个合约完成
遇到问题
执行 getNum函数时候, 得到不正常, 回显是transfer的信息
truffle(development)> contract.getNum()
{ tx: '0x4d1893d2bde57907b3ec4d9b4929ff80d3adc2e7e92264fe3fef345a0ca7f152',
receipt:
{ transactionHash: '0x4d1893d2bde57907b3ec4d9b4929ff80d3adc2e7e92264fe3fef345a0ca7f152',
transactionIndex: 0,
blockHash: '0x2d9540781aba9d5ae963bbb1853f83b8f7ce506c5273f6b581ad9dff8f90c5f0',
blockNumber: 20,
gasUsed: 21688,
cumulativeGasUsed: 21688,
contractAddress: null,
logs: [],
status: 1 },
logs: [] }
执行setnum的时候,也是得到的是
truffle(development)> contract.setNum(12)
{ tx: '0xc5c33b52e9927f6a4705317850ce4b4cb6518555dc4d9536ddc9d42ac95b0500',
receipt:
{ transactionHash: '0xc5c33b52e9927f6a4705317850ce4b4cb6518555dc4d9536ddc9d42ac95b0500',
transactionIndex: 0,
blockHash: '0xcf75f94ab4fa6d3906c16070f6e92ab4388a834c39f5f73c38cc92c0b28fbb1d',
blockNumber: 21,
gasUsed: 26708,
cumulativeGasUsed: 26708,
contractAddress: null,
logs: [],
status: 1 },
logs: [] }
truffle(development)>
估计问题可能和pure关键字有关
但是在在线的IDE(browser-solidity)中 得到以下信息,output是有的,可是不被显示出来
status 0x1 Transaction mined and execution succeed
from 0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db
to TestContract.getNum() 0x8046085fb6806caa9b19a4cd7b3cd96374dd9573
gas 3000000 gas
transaction cost 21688 gas
execution cost 416 gas
hash 0x4f29cd5e276c8ea4ec9d8f48baa44c43c7adff6ef0ca177a2cb4f2d479525b62
input 0x67e0badb
decoded input {}
decoded output {
"0": "uint256: 23"
}
logs []
value 0 wei
问题下次解决!