5,智能合约(react+区块链实战)
5-1 智能合约
运行在区块链上的代码()
语言是类js的solidity
Js
尽量找js的语法类比
后期会讲如何部署合约到区块链
这先讲语法
强类型,变量必须声明类型
Constructor 初始化
左侧js,右侧智能合约
所有合约都有地址概念
可以使用官方remix进行编译看看
虚拟环境
Jsvm本地编译环境
Web3inject,链接远程的以太坊测试链或者私有链
编译及执行部署
具体可以参考
Metamask开发的不可缺少的插件
部署成功后函数已经可以出来
修改区块链也是需要gas
合约部署后,调用函数是需要支付gas
Complie部署区块链
一个给web3链接调用函数
5-2 metamask安装及私有链搭建互相联动
在remix中jsVM虚拟机瞬间部署调用
在真实开发里面不是连接jsVM虚拟机的,而是真正链接以太坊的链,无论私有链还是说公链,测试链
在部署合约时,要从metamask插件取钱部署
在谷歌装应用需要翻墙,而火狐浏览器可以直接安装
也可以添加插件文件
创建钱包,常用密码,助记词一定不要丢,备份自己的私钥(助记词,私钥映射到其中)
助记词可以通过算法算出秘钥
下一步安装一个私有链,就是使用
测试在本地搭建一个私有链,本地的以太坊可以随便用ganache
最后怎么部署到测试链,怎么部署到主链
主链花钱还是在私有链执行
其可以快速创建个人区块链,操作还可以显示在区块上
https://www.trufflesuite.com/ganache
下载windows,已经存到百度云盘
启动后如上
点击快速启动有一大堆东西
在7545端口给了10个账号,每个账号有100个以太币
上方是需要添加的网络,可以添加本地的网络
右上角可以添加账号
可以新增币种
账户详情有二维码和地址
打开ganache后无需管就有
刚打开全新的区块是0,创世区块
后面就是交易、合约(可以部署一般不会这样做)、事件、日志
需要记住networkid 是5777 ,127.0.0.1是本机
如何使用turffle框架链接本地私有链
现在已经启动7545的服务了
要使用metamask链接此私有链网络
下方添加的是一个火星币的网络
添加本地网络在metamask上
点击网络的自定义RPC
视频演示如下
自己添加的本地链如下
名称local-7545
Rpc-url http://127.0.0.1:7545
Id 1337
ZCH
复制一下本地的第2个秘钥
4aed45798c704e884968126ad6740de8631bcb2784e609466bd6260867732c8b
导入成功后如下,已经有100个币了
有了此后
在remix中选择 部署的环境 injectweb3
选择地址则是我们的账户地址,不是私钥,可以刷新得到
可以自动监听我们的钱包,本地账号
Gas选择少一些100等
可以点击部署,将合约部署到链上,这里还没有写合约
点击后并没有马上部署成功,弹出弹框需要支付gas
视频演示效果如下
本地演示效果如下
这里显示余额不足
是因为账户的原因,链接的是第一个无钱的账号,应该链接第二个导入的账户
如下
再次部署,如下
点击确认
此时账户余额变为99.99999
花费手续费部署了合约
Gas limit不用管即可
此次进入到下方
但我们修改内容就会弹出消耗gas的窗口
只要对合约中的数据进行了修改都需要支付手续费,只读的不需要支付gas
后面的领养宠物修改值的时候都会有弹窗
这里没有转账只有部署消耗gas
若是转账就是手续费加转账的钱
5-3 solidity数据类型-布尔-数字-地址(owner区别)
1,布尔值
True false
&& || !
2.整型
Unit 无符号整型,只能表示正数
Init 任何范围书都可表示
+ - * /
<> <=
3.地址(其余语言无,此语言特有)
以太坊的交互就是地址与地址的交互
0x31ebbf3038a2A75259B86A53371b8C785F9647EB
一个42个,去掉前面0X则40位的地址
定义一个adress
(1)合约里的全局变量 msg.sender 部署合约的地址(合约的拥有者)
(2)地址有很多方法,blance查看余额 transfer 转账
在remix复制代码如下
pragma solidity ^0.4.24;
//contract 关键词新建合约
contract Counter{
//变量必须声明类型
uint num;
address owner;
//初始化
constructor(){
num = 0;
//msg.sender 谁部署合约,这个值就是谁
owner = msg.sender;
}
//函数类型 public 公用函数(在执行此函数时,谁执行合约此msg.sender就是谁)
function increment() public{
//只有最初的部署合约的人才能数字加一(要注意区分部署合约人的地址和执行合约人的地址的不同)
if (owner == msg.sender){
num +=1;
}
}
//view函数 只读取变量,不写
//声明返回值类型
function getNum() view returns (uint){
return num;
}
}
通过上述进行部署合约到链上及,区分部署合约的地址和调用合约的地址的不同
谁最早部署,constructor执行的是谁谁就就是owner
有些操作只有owner操作,若后期的发币以及课程上架下架都是创造者可以进行的操作
下方是另一个程序操作
其余地址执行写入的函数时,虽然没法真正的写入进去,但还是会消耗gas
5-4 solidity 数组和映射(代币转账)
4,字符串
“woniu”
定义很简单
String即可
5,数组
如宠物领养要存储所有的
Uint [5] arr = “woniu”;
uint [5] arr = [1,2,3,4,5];
arr[1] = 3;
arr.push(6);
for(unit i=0;i=arr.length;i++){
}
6,map
所谓的map和js的对象是一个东西
{
Name:’woniu’,
Age:18
}
//结构体(实现数字货币使用此做)
mapping(address =>uint) users;
users["address1"] = 100;
users["address2"] = 100;
//所谓代币的转账就是映射里自己存储的值
users["address1"] -= 10;
users["address2"] += 10;
pragma solidity ^0.4.24;
//contract 关键词新建合约
contract Counter{
//变量必须声明类型
uint num;
address owner;
string name = "woniu";
uint [5] arr = [1,2,3,4,5];
arr[1] = 3;
arr.push(6);
for(unit i=0;i=arr.length;i++){
}
//结构体(实现数字货币使用此做)
mapping(address =>uint) users;
users["address1"] = 100;
users["address2"] = 100;
//所谓代币的转账就是映射里自己存储的值
users["address1"] -= 10;
users["address2"] += 10;
//初始化
constructor(){
num = 0;
//msg.sender 谁部署合约,这个值就是谁
owner = msg.sender;
}
//函数类型 public 公用函数(在执行此函数时,谁执行合约此msg.sender就是谁)
function increment() public{
//只有最初的部署合约的人才能数字加一(要注意区分部署合约人的地址和执行合约人的地址的不同)
if (owner == msg.sender){
num +=1;
}
}
//view函数 只读取变量,不写
//声明返回值类型
function getNum() view returns (uint){
return num;
}
}
5-5 solidity结构体与枚举
6,结构体
结构体和map比较类似
struct Student{
uint age;
uint id;
string name;
string phone;
}
//定义一个结构体(结构体中四个字段必须满足)
woniu = Student(18,0,'woniu','13811111111')
//数组中每个元素都可以是结构体
7,枚举
变量只能在此中选
//0,1(枚举里面的元素就是对应数字)
enum sex {male,female}
//male =0