当前位置:   article > 正文

以太坊:通过Web3实现智能合约交互_python3链接ganache

python3链接ganache

以太坊:通过Web3实现智能合约交互

1. 环境准备

1.1 安装相关依赖包

​ 安装pip3

sudo apt install python3-pip -y
  • 1

​ 使用pip3安装web3 python包

pip3 install web3
  • 1

​ 安装ipython3

sudo apt install ipython3 -y
  • 1

1.2 安装ganache

​ 下载ganache

​ 输入以下命令,运行ganache(./后的内容视具体版本而定)

./ganache-2.5.4-linux-x86_64.AppImage &
  • 1

在这里插入图片描述

1.3 测试

​ 进入Python交互环境

ipython3
  • 1

​ 输入以下代码测试连接情况

from web3 import Web3
w3 = Web3(Web3.HTTPProvider("http://localhost:7545"))
w3.isConnected()
  • 1
  • 2
  • 3

在这里插入图片描述

2. 新建一个student合约

2.1 配置合约信息

​ 在contracts文件夹中新建Student.sol并输入以下内容:

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.16 <0.9.0;

contract Student{

    string name;

    constructor() {
        // name = _name;
        name = "Tom";
    }

    function getName() public view returns (string memory) {
        return name;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

2.2 编写web3脚本

2.2.1新建一个Student.py文件

​ 导入库

from web3 import Web3
import os
import sys
import getopt
import uuid
  • 1
  • 2
  • 3
  • 4
  • 5

​ 声明一些全局变量

url = "http://localhost:7545"   				# 以太坊测试链 rpc 连接端口
contract_address_file = 'contract_student.txt'  # 合约地址保存文件
abi_file = "Student/Student.abi"  				# abi 文件
bytecode_file = "Student/Student.bin"  			# 字节码文件
account_id = 0									# 默认账户
  • 1
  • 2
  • 3
  • 4
  • 5

​ 连接测试链

# 连接测试链
w3 = Web3(Web3.HTTPProvider(url))   
eth = w3.eth
print("eth connect:", w3.isConnected())
  • 1
  • 2
  • 3
  • 4

​ 设置默认账户

def set_default_account():
    """
        设置调用合约、发送交易的账户
    """
    global account_id
    eth.defaultAccount = eth.accounts[account_id]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

​ 获取abi和bytecode

def get_abi_from_file(file):
    """
       从文件中获取abi
    """
    with open(file, 'r') as f:
        return f.read() 

def get_bytecode_from_file(file):
    """
        从文件中获取字节码
    """
    with open(file, 'r') as f:
        return "0x" + f.read()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

​ 部署合约、获取合约地址

def deploy_contract(abi, bytecode):
    """
        部署合约
    """
    contract = eth.contract(abi=abi, bytecode=bytecode)     # 创建合约
    tx_hash = contract.constructor().transact()             # 部署合约(发送构造函数的交易,需相对应合约中的参数)
    tx_receipt = eth.waitForTransactionReceipt(tx_hash)     # 等待交易回执
    print("contract address:", tx_receipt.contractAddress)  # 合约地址
    # 保存合约
    global contract_address_file
    with open(contract_address_file, "w") as f:
        f.write(tx_receipt.contractAddress)
    # 通过地址获取已部署合约
    deployed_contract = eth.contract(address=tx_receipt.contractAddress, abi=abi)
    return deployed_contract

def get_deployed_contract(abi, bytecode):
    """
        获取部署合约,如果本地已保存合约地址,则调用该地址的合约,否则重新创建一个新的合约
    """
    try:
        # 尝试获取已有合约
        with open(contract_address_file, "r") as f:
            contract_address = f.read()
        print("contract address:", contract_address)
        deployed_contract = eth.contract(address=contract_address, abi=abi)
        return deployed_contract
    except IOError:
        # 获取已有合约失败则重新部署新合约
        return deploy_contract(abi, bytecode)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

​ main方法

if __name__ == '__main__':
    set_default_account()
    abi = get_abi_from_file(abi_file)
    bytecode = get_bytecode_from_file(bytecode_file)
    deployed_contract = get_deployed_contract(abi, bytecode)
    print(deployed_contract.functions.getName().call())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
2.2.2 编译合约与运行

​ 编译

solc --abi --bin --overwrite -o Student Student.sol 
  • 1

​ 运行

python3 Student.py
  • 1

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/123781
推荐阅读
相关标签
  

闽ICP备14008679号