web3j 合约方法调用源码分析

文章目录

调用方法流程
  1. 方法包括方法名,参数 返回值 (Function)
  2. 对方法进行编码(FunctionEncoder.encode)
  3. 根据none pirce limit address 方法编码 创建交易信息(RawTransaction.createTransaction)
  4. 签名交易信息 (TransactionEncoder.signMessage)
  5. 并转成16进制数据 (Numeric.toHexString)
  6. 发送交易
  7. 通过交易原数据和签名拿到hash(TransactionUtils.generateTransactionHashHexEncoded)
Function
java 复制代码
  public Function(String name, List<Type> inputParameters, List<TypeReference<?>> outputParameters) {
        this.name = name;
        this.inputParameters = inputParameters;
        this.outputParameters = Utils.convert(outputParameters);
    }
RawTransaction
java 复制代码
  protected RawTransaction(BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, String to, BigInteger value, String data, BigInteger gasPremium, BigInteger feeCap) {
        this.nonce = nonce;
        this.gasPrice = gasPrice;
        this.gasLimit = gasLimit;
        this.to = to;
        this.value = value;
        this.data = data != null ? Numeric.cleanHexPrefix(data) : null;
        this.gasPremium = gasPremium;
        this.feeCap = feeCap;
    }
Credentials
java 复制代码
 public static Credentials create(ECKeyPair ecKeyPair) {
        String address = Numeric.prependHexPrefix(Keys.getAddress(ecKeyPair));
        return new Credentials(ecKeyPair, address);
    }
signMessage
java 复制代码
 public static byte[] signMessage(RawTransaction rawTransaction, Credentials credentials) {
        byte[] encodedTransaction = encode(rawTransaction);
        Sign.SignatureData signatureData = Sign.signMessage(encodedTransaction, credentials.getEcKeyPair());
        return encode(rawTransaction, signatureData);
    }
generateTransactionHash
java 复制代码
 public static byte[] generateTransactionHash(RawTransaction rawTransaction, Credentials credentials) {
        byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
        return Hash.sha3(signedMessage);
    }
toHexString
java 复制代码
 public static String toHexString(byte[] input) {
        return toHexString(input, 0, input.length, true);
    }
    
    
    public static String toHexString(byte[] input, int offset, int length, boolean withPrefix) {
        StringBuilder stringBuilder = new StringBuilder();
        if (withPrefix) {
            stringBuilder.append("0x");
        }

        for(int i = offset; i < offset + length; ++i) {
            stringBuilder.append(String.format("%02x", input[i] & 255));
        }

        return stringBuilder.toString();
    }
RawTransactionManager
java 复制代码
 public EthSendTransaction sendTransaction(BigInteger gasPrice, BigInteger gasLimit, String to, String data, BigInteger value, boolean constructor) throws IOException {
        BigInteger nonce = this.getNonce();
        RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, gasPrice, gasLimit, to, value, data);
        return this.signAndSend(rawTransaction);
    }
合约执行流程
java 复制代码
   //1
   this.executeTransaction(function);
   //2
   this.executeTransaction(function, BigInteger.ZERO);
   //3
   this.executeTransaction(FunctionEncoder.encode(function), weiValue, function.getName());
   //4 weiValue如果是转eth就是数量 如果是调用合约方法就是data
   this.executeTransaction(data, weiValue, funcName, false);
   //5
    TransactionReceipt receipt = this.send(this.contractAddress, data, weiValue, this.gasProvider.getGasPrice(funcName), this.gasProvider.getGasLimit(funcName), constructor);
    //6       
    this.transactionManager.executeTransaction(gasPrice, gasLimit, to, data, value, constructor);
    //7
    this.sendTransaction(gasPrice, gasLimit, to, data, value, constructor);
FastRawTransactionManager

维护了一个nonce 避免每次发送请求都区获取nonce

可以最大限度地减少向节点发送RPC请求的次数,从而提高交易发送的响应速度。

NoOpProcessor

使用NoOpProcessor的一个常见场景是,当我们只需要发送交易,而不关心区块事件或其他通知时,可以将其设置为事件处理器,避免不必要的事件处理开销。

这允许调用方对提交到网络的交易拥有交易哈希。

java 复制代码
     ///使用7
     public  static TransactionManager getTxManager(Credentials credentials, Web3j web3j){
        NoOpProcessor processor = new NoOpProcessor(web3j);
        return new FastRawTransactionManager(web3j, credentials, processor);
    }
    ///使用
    this.sendTransaction(gasPrice, gasLimit, to, FunctionEncoder.encode(function), BigInteger.ZERO, false);
    
    
     public  static String sendEthTransaction(Credentials credentials, Web3j web3j,BigInteger weiValue,BigInteger gasPrice, BigInteger gasLimit, String to){
        try {
           return getTxManager(credentials,web3j).sendTransaction(gasPrice, gasLimit, to, "", weiValue, false).getTransactionHash();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
代码
kotlin 复制代码
@Throws(
    IOException::class,
    ExecutionException::class,
    InterruptedException::class
)
fun signTokenTransaction(
    amount: String,
    to: String,
    privateKey: String,
    coinAddress: String,
    decimals: Int,
    nonce: BigInteger
): Pair<String, String> {
    //支付的矿工费
    val gasPrice = getWeb3j().ethGasPrice().send().gasPrice
    val gasLimit = BigInteger("60000")
    val credentials = Credentials.create(privateKey)
    val amountWei =
        BigDecimal.TEN.pow(decimals).multiply(BigDecimal(amount)).toBigInteger()
    //封装转账交易
    val function = Function(
        "transfer",
        listOf<Type<*>>(
            Address(to),
            Uint256(amountWei)
        ), emptyList()
    )
    val data = FunctionEncoder.encode(function)
    //签名交易
    val rawTransaction = RawTransaction.createTransaction(
        nonce,
        gasPrice,
        gasLimit,
        coinAddress,
        data
    )
    val signMessage = TransactionEncoder.signMessage(rawTransaction, credentials)

    val hexValue = Numeric.toHexString(signMessage)
    val hash = TransactionUtils.generateTransactionHashHexEncoded(
        rawTransaction,
        Credentials.create(privateKey)
    )
    return hexValue to hash

    //广播交易
//    return getWeb3j().ethSendRawTransaction(Numeric.toHexString(signMessage)).sendAsync().get()
//        .transactionHash
}
相关推荐
会跑的葫芦怪5 小时前
Web3开发中的前端、后端与合约:角色定位与协作逻辑
前端·web3·区块链
小攻城狮长成ing16 小时前
从0开始学区块链第10天—— 写第二个智能合约 FundMe
web3·区块链·智能合约·solidity
leijiwen1 天前
web3品牌RWA资产自主发行设计方案
web3·区块链
元宇宙时间1 天前
Nine.fun:连接现实娱乐与Web3经济的全新生态
人工智能·金融·web3·区块链
只会写Bug的程序员1 天前
【职业方向】2026小目标,从web开发转型web3开发【一】
前端·web3
野老杂谈1 天前
【Solidity 从入门到精通】第3章 Solidity 基础语法详解
web3·solidity
leijiwen1 天前
S11e Protocol 数字身份体系架构白皮书
架构·web3·区块链·品牌·rwa
野老杂谈1 天前
【Solidity 从入门到精通】第2章 Solidity 语言概览与环境搭建
web3·区块链·智能合约·solidity·remix ide
MicroTech20252 天前
微算法科技(NASDAQ MLGO):DPoS驱动区块链治理与DAO机制融合,共筑Web3.0坚实基石
科技·web3·区块链