以太坊交互

区块链中级.以太坊开发
From:JamesZou & 传智播客研究院 & 传智播客区块链

一. 账户

1. 以太坊账户

账户分两种:外部账户 和 合约账户

1.1 外部账户
  • 用户使用的账户,包含 地址和私钥

  • 操作

    • 查看余额
    • 可以转账交易
    • 调用合约
  • 特点:

    • 创建不需要网络,本地生成(钱包生成,自己生成,纸钱包等)
    • 被私钥控制
    • 仅有余额,没有代码
    • 可以发送交易(transaction)
    • 每个以太坊网络中都可以使用,但是金额互相独立,只要符合以太坊网络规则即可
      在这里插入图片描述
1.2. 合约账户
  • 由外部账户创建的智能合约实例,部署后返回一个地址,这个地址就是合约账户(有金额,有代码逻辑)

  • 操作:

    • 由外部账户发送消息激活合约账户的代码
    • 接收转账,向外转账
    • 调用其它合约
  • 特点

    • 拥有 ether 余额
    • 含有执行代码
    • 代码仅在该合约地址发生交易或者收到其他合约发送的信息时才会被执行
    • 拥有自己的独立存储状态,且可以调用其他合约

    注意:合约账户由外部账户或合约代码逻辑进行创建,一旦部署成功,只能按照预先写好的合约逻辑进行业务交互,不存在其他方式直接操作合约账户或更改已部署的合约代码。

在这里插入图片描述

  • 合约源码与实例

    合约是“类”,可以创建很多“实例对象”

    let a = new Dog();

    let b = new Dog();

在这里插入图片描述

在这里插入图片描述

2.2 Ropsten

在这里插入图片描述

3.转账

3.1 对比
  • 对比

    • 传统银行:在不同的网络里面,同一个账户的金额可能不同
银行开户人金额取款密码(存储在银行)
招商银行华仔10000元123456
建设银行华仔20000元654321
农业银行华仔15000元235677
中国银行华仔30000元876644
  • 以太坊网络

    • 不同的银行相当于不同的区块链网络, 同一个开户人在不同银行的存款是不一样的。
    • 在传统中心化网络里面,密码是存储在银行的中心化的服务器里面的。
    • 不同的区块链网络, 拥有相同的账户信息. 密码是存储在用户端(private key)。
    • 不同之处是各个网络无法互相转账,而传统银行是可以的。
区块链网络账户地址金额私钥(取款用,存储在用户端)
main network0xd5a2…10000 ether0x358b35069…
Ropsten network0xd5a2…20000 ether0x358b35069…
kovan network0xd5a2…15000 ether0x358b35069…
rinkeby network0xd5a2…30000 ether0x358b35069…
  • 演示转账
3.2 几个概念
  • gas(汽油)- 油耗

    由于以太坊是公链,所有人都可以自由的参与,为了防止垃圾数据充斥网络,所以以太坊上规定每一个操作都是要有成本的,这个成本由gas来体现,你要转账,部署智能合约,调用智能合约方法,都要消耗一定数量的gas。

    单位 : 1 eth = 10 ^18 wei
    在这里插入图片描述

  • gasprice(汽油价格) - 油价

    虽然操作消耗gas,但是最终真正花的还是eth,所以就有一个转换率的问题,gasprice就是起到一个汇率的作用,它代表的是一个gas值多少eth,gas*gasprice就是最终的手续费,也就是从你账户扣除的eth。

    这种设计就可以保证用户在以太坊上的操作的手续费不会随着eth的价格而发生剧烈的变动(例如:如果eth涨,那么可以调低gasprice来降低手续费),

  • gaslimit(汽油上限)- 油箱

    以太坊规定,每笔交易的gas最少21000,矿工可以调整这个值,所以最终的花费的gas是不确定的,所以以太坊就设置了gaslimit,这个代表的是最多给旷工这么多gas(防止自己写的合约里面有死循环),如果最终使用的gas少于这个gaslimit,剩余的还会返给你的,但是如果你的gaslimit不足以支付这次交易,那就是不会退回的,并且交易也就失败了,转账的额度也是回不来了,所以你转账设置的limit一定要大于21000。

3.3 转账流程

在这里插入图片描述

  • 解释点下确定按钮的流程:

    1.点击submit

    2.地址通过get请求发给了服务器

    3.web3.js 创造了一个转账 (translation) (什么是转账,转账包含什么信息)

    nonce,to,value,gas,gaslimit,密码学相关 有privatekey生成

    4.为什么需要等待, 后台server发送translation 到rinkeby网络

    5.等待挖矿,30秒左右

    6.后台服务器把成功信息反馈给前端

在这里插入图片描述

3.4 转账具体流程
  1. translation提交给一个node(如何修改node,选择node?)
  2. node可能在某个时间内收到很多个translation
  3. node对translation排序,挖矿
  4. node算好nonce就会广播给全网
  5. 最先算出nonce的node会得到挖矿奖励

在这里插入图片描述

在这里插入图片描述

4.区块时间

在这里插入图片描述

4.1 区块时间原理
  1. 区块时间 算 0000 开头是不科学的. 是简易算法.
  2. 实际算法是计算一个hash 小于某种特殊值.
  3. hash值的范围 0 ~ 1.15x10^77 跟摇色子一样.
    在这里插入图片描述
4.2 区块时间详解
  • blocktime = time to find a solution

在这里插入图片描述

在这里插入图片描述

二. Solidity

1. Solidity简介

  1. 以太坊编写智能合约的语言,文件扩展名 .sol
  2. 强类型编程语言(变量类型有多种,例如int byte bool struct 等,类型之间转换时需要强转)
  3. 与javascript类似(但是JavaScript是弱类型的语言,一个var关键字自动识别数据类型)
  4. 一堆坑
  5. api手册 -》 Solidity中文手册

2.开发环境

  • Mist钱包 - 不好用,问题较多

  • Remix在线编程

  • Remix本地环境

在这里插入图片描述

3.第一个合约

  • 智能合约概览
每个合约中可包含:

- 状态变量(State Variables) : 就是成员变量,这个数据是上链的。
- 函数(Functions)
- 函数修饰符(Function Modifiers)
- 事件(Events)
- 结构类型(Structs Types)
- 枚举类型(Enum Types)
- mapping(key => value) 如: map[1] = 2
  • 便写一个 接收消息的方法
pragma solidity ^0.4.25;

contract Inbox{ 
    string public message; 
    
    function getMessage() public constant returns(string){
        return message;
    }
  
    function setMessage(string newMessage) public{
        message = newMessage;
    }
}
  • 语法解析

在这里插入图片描述

4.编译合约

4.1 原理
  • 使用remix,由高级语言变成机器语言

    1. solidity —> bytecode - 机器语言,区块链系统读取
    2. solidity —> ABI (application binary interface) - 方便程序员调用
  • 图示

在这里插入图片描述

4.2 bytecode

6080604052610410806100136000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063368b87721461005c578063ce6d41de146100c5578063e21f37ce14610155575b600080fd5b34801561006857600080fd5b506100c3600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506101e5565b005b3480156100d157600080fd5b506100da6101ff565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561011a5780820151818401526020810190506100ff565b50505050905090810190601f1680156101475780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561016157600080fd5b5061016a6102a1565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101aa57808201518184015260208101905061018f565b50505050905090810190601f1680156101d75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b80600090805190602001906101fb92919061033f565b5050565b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102975780601f1061026c57610100808354040283529160200191610297565b820191906000526020600020905b81548152906001019060200180831161027a57829003601f168201915b5050505050905090565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103375780601f1061030c57610100808354040283529160200191610337565b820191906000526020600020905b81548152906001019060200180831161031a57829003601f168201915b505050505081565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061038057805160ff19168380011785556103ae565b828001600101855582156103ae579182015b828111156103ad578251825591602001919060010190610392565b5b5090506103bb91906103bf565b5090565b6103e191905b808211156103dd5760008160009055506001016103c5565b5090565b905600a165627a7a723058201486092ea8103d4816d5aa6177b30372d94ec850544312021159c20f3b7a505b0029

4.3 abi
  • (application binary interface,应用二进制接口)

    json格式的描述文件:

[
	{
		"constant": false,
		"inputs": [
			{
				"name": "newMessage",
				"type": "string"
			}
		],
		"name": "setMessage",
		"outputs": [],
		"payable": false,
		"stateMutability": "nonpayable",
		"type": "function"
	},
	{
		"constant": true,
		"inputs": [],
		"name": "getMessage",
		"outputs": [
			{
				"name": "",
				"type": "string"
			}
		],
		"payable": false,
		"stateMutability": "view",
		"type": "function"
	},
	{
		"constant": true,
		"inputs": [],
		"name": "message",
		"outputs": [
			{
				"name": "",
				"type": "string"
			}
		],
		"payable": false,
		"stateMutability": "view",
		"type": "function"
	},
	{
		"inputs": [],
		"payable": true,
		"stateMutability": "payable",
		"type": "constructor"
	}
]
4.4 调用

以太坊为了方便智能合约的开发、学习和测试,开启了几条全新的区块链,与主网络特性相同,但测试网络中的以太币价值更低,也更容易得到。这样不至于在主网络上开发出现 BUG 造成以太币的损失。

当然我们也可以搭建私有的测试网络,不过区块链的去中心化特点,需要更多的节点运行才能达到理想效果,好在以太坊有公开的测试网络,而我们接入也更容易。

4.4.1 运行环境
  • vm

    • account 虚拟账户5个,每个账户默认100eth。
    • 没挖矿,直接返回结果,便于开发测试
  • 网页环境

    • injected web3
    • 与metamask结合紧密
  • 自定义环境

    • web3 provider
    • 链接自己本地启动的区块链环境(truffle,ganache,私有链等)
4.4.2 部署合约
  • 部署成功后返回合约地址,如:0x27baf63ea560973e9f8f333a39239967f96c5703

  • 部署合约也是一笔交易,只不过不用填写to字段,且数据输入字段填写为合约字节码。

在这里插入图片描述

  • 查看浏览器

在这里插入图片描述

4.4.3 调用合约
  • 手动调用,我们使用手动调用,调用合约的操作分为两种类型

    • send:所有改变区块链数据状态的叫做是send操作,相当于发起一笔交易,特点是花钱,大约10s~30s(矿工确认)返回结果。
    • call:所有读取区块链合约数据的操作成为call操作,它的特点是迅速返回无需花钱

    在这里插入图片描述

  • 通过web3调用

在这里插入图片描述

4.4.4 对比总结
对比项函数调用call函数调用 send transaction
数据状态不修改智能合约的数据修改智能合约的数据
返回值函数可以返回数据函数不能返回数据, 因为函数需要花时间执行
执行速度立刻执行需要十几秒才能执行完毕,返回值是transaction的hash
成本免费要花钱 钱!!!
4.5 析构函数
function destroy() {
	//析构函数,销毁当前合约,并把它所有资金发送到给定的地址
      //1.将合约里的 余额 转给 传入的地址
      //2.标记当前合约 为 销毁状态
	selfdestruct(msg.sender);
}

调用之后,合约仍然存在于区块链之上,但是函数无法被调用,调用会抛出异常。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值