欢迎来到我的博客
区块链之solidity详解(一)-鱼卷少年

作为一个学习区块链的人,陈雁升怎么能缺少 solidity 这门语言呢。 solidity 是基于以太坊的合约编写语言,它入门简单,有编程语言学习基础的人,很快就能看懂一些代码逻辑。
当然了,我是学过 java 和 python 的,一开始去看的时候,对于一些语法结构,我还真有点不习惯,不过敲得多了,也渐渐习惯了。
在学习的时候,你会发现一些跟其他的编程语言不一样的地方,比如说区块链特有的 address 变量,以及 pure 、constant 、 payable 、 view 等修饰符。我也有点迷迷糊糊的,但不怕,不是还有官方文档吗陈朝波 。
现在我来把一些学习笔记逐渐分享出来, solidity 虽然简单,但还是存在比较多知识点的,因此我分几次来讲,后面结合一个合约实例进行讲解就差不多了。
在开始之前,还要提醒一句,合约代码运行是需要消耗 Gas 的,可以理解为消耗”钱”的鸿蒙圣祖。
因此在后面真正运用 solidity 时,更多的是要求程序员在编写合约时,实现了业务逻辑和合约规则后,需要进一步把代码优化到极致,从而减少消耗,节省资源。
状态变量(全局变量)
pragma solidity ^0.4.0;contract SimpleStorage { uint userCount; //状态变量永久存储用户的人数 //....}
局部变量
pragma solidity ^0.4.0;contract SimpleStorage { uint userCount; //状态变量永久存储用户的人数 //.... uint someVariable; uint[] data; // 函数 function f() { //局部变量 uint[] x = data; x.push(2); }}
函数
函数的基本结构为:
function (<parameter types>) {internal|external} [pure|constant|view|payable][returns (<return types>)]
// internal|external //内部库被作为内部调用阮明园 ,不允许地址直接访问这些工具类方法//内部实现map片段function map(uint[] memory self,function (uint) pure returns (uint) f) internal pure returns (uint[] memory r) { r = new uint[](self.lngth); for (uint i = 0;i < self.length; i++) { r[i] = f(self[i]); }}
外部调用指的是可以被其他智能合约调用,external 和 public 的意思是不一样的
pragma solidity ^0.4.11;contract Oracle { struct Request { bytes data; function(bytes memory) external callback; } Request[] requests; event NewRequest(uint); function query(bytes data, function(bytes memory) external callback) public{ requests.push(Request(data, callback)); NewRequest(requests.length - 1); } function reply(uint requestID, bytes response) public { requests[requestID].callback(response);} }contract OracleUser { Oracle constant oracle = Oracle(0x1234567);function buySomething() { oracle.query("USD", this.oracleResponse); } function oracleResponse(bytes response) public { require(msg.sender == address(oracle)); }}
函数修饰符
pragma solidity ^0.4.0;contract SimpleStorage { address public seller; // 函数修饰符//比如写个销毁合约的函数,除了合约创建者之外不希望被别人调用,这时候就用到了函数修饰符,对函数逻辑进行限制。 modifier onlySeller() { require(msg.sender == seller); _; } //这里的写法是 function 函数名() 调用范围函数修饰符 {}function abort() public onlySeller { // ... } function bid() public payable {//... }}
pure|constant|view|payable
pure 完全禁止读写状态变量。
constant,view 可以读取状态变量,但是不能改变。
payable 表示函数可以接收 Eth
其中,pure|constant|view 对状态变量的操作做了严格的限制司光敏 ,也就是说都不能修改状态卓琳妹妹 ,原因是,让这些限制的函数不消耗 Gas
事件
事件在于智能合约内部的操作与外界操作的调用。事件的主要作用在于 Dapp,调用合约的方法得到返回值后明一居士 ,通过事件反馈给 js,从而展示在网页上,还可以用于异步调用
event Deposit { address indexed _from, bytes32 indexed _id, uint _value }; //注册事件 function deposit(bytes32 _id) public payable { Deposit(msg.sender, _id, msg.value); // 执行事件 }
完整实例
var abi = ""; var ClientReceipt = web3.eth.contract(abi); //通过这个地址调用经过abi封装的参数的智能合约 var clientReceipt = ClientReceipt.at("0x1223421323...dasd"); var event = clientReceipt.Deposit();//智能合约的事件 //js的watch监听方法 event.watch(function(error,result){ if(!error)console.log(result); }); // 或者通过 回调的方法 var event = clientReceipt.Deposit(function(error花鹩哥 ,result){ if(!error)console.log(result); });
类型
类型有基本类型、值类型(参数或赋值)、整数类型 int/uint 默认256位、布尔类型 Booleans,这里除了整数类型是比较特殊外,其余的和平时的编程语法差不多。
整数型的表示为 int/uint,分别代表有符号和无符号的整数郑丰喜。我们可以从 uint8 逐步到 uint256,分别表示无符号的2的8次方到256次方,不写默认为256次方。
地址类型
以太坊的地址为20字节超级店小二,代表了操作合约的用户,所有操作都是用地址进行的地址的操作和成员
balance、transfer,地址的余额以及转账。
send,低等级的 transfer。
call、callcode、delegatecall,ABI 相关操作
字节数组
固定大小字节数组
byte byte1~byte32
动态大小字节数组
bytes,字节
string,utf8的字符串注:这两种都不属于值类型
枚举类型
enum SomeData(DEFAULT,ONE,TWO) //定义枚举类型 SomeData someData; function SimpleEnum(){ someData = SomeData.DEFAULT; //调用值 } function setValues(uint _value) { require(uint(SomeData.TWO) >= _value); someData = SomeData(_value);} function getValue() constant returns (uint) { return uint(someData); }
函数类型,归属为值类型,可以想 js 那样,作为回调函数进行参数传递
引用类型(参考类型)
关键字 storage 和 memory , storage 存储在存储器中草帽饼的做法 ,持久化存储, memory 存在内存里,不是持久的
结构体
struct Voter { uint weight; bool voted; address delegate; uint vote; } //结构体内部可以放匿名函数或者映射,思路更加自由 struct Funder { address addr; uint amount; } struct Campaign { address beneficiary; uint fundingGoal; uint numFunders; uint amount; mapping (uint => Funder) funders; } struct Request { bytes data; function(bytes memory) external callback;}
映射类型
//mapping(_KeyType => _ValueType) // 例如在token类合约中 存储用户(地址)和余额的对应关系 mapping(address => uint) public balances; // 映射嵌套 mapping(address => mapping(address => uint) public balances;
delete 操作符
它比较特殊,delete 后面可以接很多变量,结果是将变量根据数据类型进行清空
pragma solidity ^0.4.0; contract DeleteExample { uint data; uint[] dataArray; function f() public {uint x = data;delete x; // x 设置为 0delete data; // data 设置为 0uint[] storage y = dataArray;delete dataArray; // dataArray 清空 } }
反过来一想,这不是在锻炼程序员的优化能力吗,一举两得了啊哈哈哈反乌托邦公职。

今日鸡汤
这个世界,每天都提醒我一个道理,读写结合 挑战与机遇同在

鱼卷少年
我来倾听你的烦恼你来书写我的幽默愿你筑梦远行归来仍是少年