web3j 合约方法调用源码分析

简介: 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
  public Function(String name, List<Type> inputParameters, List<TypeReference<?>> outputParameters) {
        this.name = name;
        this.inputParameters = inputParameters;
        this.outputParameters = Utils.convert(outputParameters);
    }
RawTransaction
  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
 public static Credentials create(ECKeyPair ecKeyPair) {
        String address = Numeric.prependHexPrefix(Keys.getAddress(ecKeyPair));
        return new Credentials(ecKeyPair, address);
    }
signMessage
 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
 public static byte[] generateTransactionHash(RawTransaction rawTransaction, Credentials credentials) {
        byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
        return Hash.sha3(signedMessage);
    }
toHexString
 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
 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);
    }
合约执行流程
   //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的一个常见场景是,当我们只需要发送交易,而不关心区块事件或其他通知时,可以将其设置为事件处理器,避免不必要的事件处理开销。

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

     ///使用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);
        }
    }
代码
@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
}
相关文章
|
搜索推荐 数据安全/隐私保护
Web 开发会话技术之 -Cookie介绍以及源码分析和图分析
Web 开发会话技术之 -Cookie介绍以及源码分析和图分析
89 0
|
中间件 新制造 调度
量化合约系统开发(web3.0技术开发)丨合约量化系统开发(demo及源码)
  智能制造则是利用先进的数字化、网络化、智能化技术,建立高度集成化的制造系统,实现远程监测、即时调度、智能决策、智能优化等功能。智能制造提供了更高效、精准、灵活的生产方式,有效地提升了制造业的质量和效率。在智能制造中,人工智能技术被视为实现智能制造的重要支撑,可以扩大智能制造的深度和广度
|
JSON 前端开发 JavaScript
佛萨奇2.0智能合约系统开发(web3.0技术开发)丨佛萨奇2.0开发源码分析
区块链本质上是一个去中心化的分布式账本数据库,由多个服务器组成,不可更改和伪造,类似于银行系统,不同的是区块链可以使每个人手上都有这个账本,账本公开所有人都可以查看;
|
存储 前端开发 区块链
分析:web3.0特性介绍以及系统开发合约技术详细方案
分析:web3.0特性介绍以及系统开发合约技术详细方案
|
人工智能 前端开发 物联网
web3.0游戏DApp系统开发合约定制方案技术介绍
web3.0游戏DApp系统开发合约定制方案技术介绍
|
设计模式 缓存 前端开发
web九大组件之---HandlerAdapter适配器模式实践源码分析【享学Spring MVC】
web九大组件之---HandlerAdapter适配器模式实践源码分析【享学Spring MVC】
web九大组件之---HandlerAdapter适配器模式实践源码分析【享学Spring MVC】
|
XML 缓存 前端开发
【小家Spring】Spring容器(含父子容器)的启动过程源码级别分析(含web.xml启动以及全注解驱动,和ContextLoader源码分析)(下)
【小家Spring】Spring容器(含父子容器)的启动过程源码级别分析(含web.xml启动以及全注解驱动,和ContextLoader源码分析)(下)
【小家Spring】Spring容器(含父子容器)的启动过程源码级别分析(含web.xml启动以及全注解驱动,和ContextLoader源码分析)(下)
|
设计模式 JSON 前端开发
【小家Spring】Spring容器(含父子容器)的启动过程源码级别分析(含web.xml启动以及全注解驱动,和ContextLoader源码分析)(中)
【小家Spring】Spring容器(含父子容器)的启动过程源码级别分析(含web.xml启动以及全注解驱动,和ContextLoader源码分析)(中)
【小家Spring】Spring容器(含父子容器)的启动过程源码级别分析(含web.xml启动以及全注解驱动,和ContextLoader源码分析)(中)
|
前端开发 Java 容器
【小家Spring】Spring容器(含父子容器)的启动过程源码级别分析(含web.xml启动以及全注解驱动,和ContextLoader源码分析)(上)
【小家Spring】Spring容器(含父子容器)的启动过程源码级别分析(含web.xml启动以及全注解驱动,和ContextLoader源码分析)(上)
【小家Spring】Spring容器(含父子容器)的启动过程源码级别分析(含web.xml启动以及全注解驱动,和ContextLoader源码分析)(上)
|
新零售 Java 区块链
合约错误:org.web3j.protocol.exceptions.TransactionException:Error processing request:unknown transaction
在执行一个 ERC20 智能合约的transfer调用时发生的org.web3j的一个交易错误: org.web3j.protocol.exceptions.TransactionException: Error processing request: unknown transaction。
2546 0