Ethereum smart contract interactive call, Web3 JS and web3j

Big tail 2022-04-04 06:42:58 阅读数:882

ethereum smart contract interactive web3

Introduction

Next to the last article 《 Use hardhat Deploy solidity Smart contract to test network 》
After deploying the contract , So how to interact with blockchain ? The main content of this section is to use web3.js and web3j To interact with the blockchain and the contracts on the chain . among web3.js It belongs to javascript The version of the ,
web3j yes java Version of .

The type of contract interaction

Ethereum can be regarded as a public database , This database provides access to 、 Write function , But you can't delete .
Initiating a transaction is actually writing the transaction into the database , Write library can't write for nothing , Other nodes help you record data , You have to pay some fees to the node that helps you record , This cost is what we often see gas. So all on Ethereum The operation of changing the data on the chain takes gas Of , And reading is free .
We can simply divide the types of contract transactions into the following three types :
1. Read only call
2. payment gas Call to
3. payment gas and value Call to

1,2 We have also talked about both above , So what's the third one . The third case is that the contract will be invoked ETH Go to the contract , This value This is the value of the transfer , The contract is acceptable ETH Of .
If you want a contract to receive ETH need , The method called plus payable Keyword declaration , There should be a statement in addition to this contract receive() Method , Indicates that this contract can accept ETH.
stay solidity 0.6.10 Medium is receive, The declarations of methods may vary from version to version .

receive() payable external {}

Get down to business , Let's get to the point

Use web3.js Interact with contracts

Introduce in the project web3.js

npm install web3

Project skeleton

 var Web3 = require('web3');
var web3 = new Web3("https://rinkeby.infura.io/v3/7d00bf84530c4264969a4f0f231de8b6");
var privateKey = " Private key ";
var contractAbi = [{
"inputs":[],"name":"getBalance","outputs":[{
"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{
"inputs":[],"name":"getName","outputs":[{
"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{
"inputs":[],"name":"name","outputs":[{
"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{
"inputs":[],"name":"payETH","outputs":[],"stateMutability":"payable","type":"function"},{
"inputs":[{
"internalType":"string","name":"_name","type":"string"}],"name":"setName","outputs":[],"stateMutability":"nonpayable","type":"function"},{
"stateMutability":"payable","type":"receive"}];
var contractAddress = "0xb19c13d0A37cDDE5c1F969a0d9BD6a50B3A11B4E"
var hello = new web3.eth.Contract(contractAbi, contractAddress);
main()
.then(() => process.exit(0))
.catch(error => {

console.error(error);
process.exit(1);
});
async function main(){

await getName();
}
async function getName(){

var name = await hello.methods.getName().call();
console.log(name);
}

Read only call

 async function getName(){

var name = await hello.methods.getName().call();
console.log(name);
}
async function getBalance(){

var balance = await hello.methods.getBalance().call();
console.log("balance = "+balance);
}

payment gas Call to

 async function setName(){

var name = "Jack";
var functionEncode = await hello.methods.setName(name).encodeABI();
var sign = await web3.eth.accounts.signTransaction({

gas: 300000,
to: contractAddress,
data: functionEncode,
}, privateKey);
var result = await web3.eth.sendSignedTransaction(sign.rawTransaction);
console.log("setName txHash = "+result.transactionHash);
}

payment gas and value Call to

 async function reviceETH(){

var ethValue = 100;
var functionEncode = await hello.methods.reviceETH().encodeABI();
var sign = await web3.eth.accounts.signTransaction({

gas: 300000,
to: contractAddress,
data: functionEncode,
value: ethValue
}, privateKey);
var result = await web3.eth.sendSignedTransaction(sign.rawTransaction);
console.log("reviceETH resultTxHash = "+result.transactionHash);
}

Execution results
 Insert picture description here

Use web3j Interact with contracts

What we use here is maven project , The first step is to introduce web3j My bag

introduce pom

 <dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>3.4.0</version>
</dependency>

Code

Java Version of the direct code , That is, the call of the above three methods


import org.junit.Test;
import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.FunctionReturnDecoder;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.*;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.TransactionEncoder;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.request.Transaction;
import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.gas.DefaultGasProvider;
import org.web3j.utils.Numeric;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class We3jTest2 {

public static String node = "https://rinkeby.infura.io/v3/7d00bf84530c4264969a4f0f231de8b6";
Web3j web3j;
Credentials credentials;
{

web3j = Web3j.build(new HttpService(node));
credentials = Credentials.create(" Private key ");
}
public static final String contractAddress = "0xb19c13d0A37cDDE5c1F969a0d9BD6a50B3A11B4E";
/** * Call the contract's read-only method , There is no need to gas * @throws Exception */
@Test
public void getName() throws Exception {

Function function = new Function(
"getName",
Collections.emptyList(),
Arrays.asList(new TypeReference<Utf8String>(){
}));
String encodedFunction = FunctionEncoder.encode(function);
org.web3j.protocol.core.methods.response.EthCall response = web3j.ethCall(
Transaction.createEthCallTransaction(null, contractAddress, encodedFunction),
DefaultBlockParameterName.LATEST)
.sendAsync().get();
List<Type> results = FunctionReturnDecoder.decode(response.getValue(), function.getOutputParameters());
Utf8String preValue = (Utf8String)results.get(0);
System.out.println(preValue.getValue());
}
/** * Need to pay gas Methods * @throws Exception */
@Test
public void setName() throws Exception {

Function function = new Function(
"setName",
Arrays.asList(new Utf8String("Tom")),
Collections.emptyList());
BigInteger nonce = getNonce(credentials.getAddress());
String encodedFunction = FunctionEncoder.encode(function);
BigInteger gasLimit = new BigInteger("300000");
RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, DefaultGasProvider.GAS_PRICE,gasLimit, contractAddress, encodedFunction);
org.web3j.protocol.core.methods.response.EthSendTransaction response =
web3j.ethSendRawTransaction(Numeric.toHexString(TransactionEncoder.signMessage(rawTransaction, credentials)))
.sendAsync()
.get();
String transactionHash = response.getTransactionHash();
System.out.println(transactionHash);
}
/** * Need to pay gas and value Contract method call * @throws Exception */
@Test
public void payETH() throws Exception {

BigInteger nonce = getNonce(credentials.getAddress());
Function function = new Function("payETH",
Collections.EMPTY_LIST,
Collections.EMPTY_LIST);
String functionEncode = FunctionEncoder.encode(function);
BigInteger value = new BigInteger("200");
// With no need to pay value Method call for , The difference is to pass one more eth In quantity value Parameters 
RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, DefaultGasProvider.GAS_PRICE,DefaultGasProvider.GAS_LIMIT, contractAddress, value,functionEncode);
org.web3j.protocol.core.methods.response.EthSendTransaction response =
web3j.ethSendRawTransaction(Numeric.toHexString(TransactionEncoder.signMessage(rawTransaction, credentials)))
.sendAsync()
.get();
String transactionHash = response.getTransactionHash();
System.out.println(transactionHash);
}
private BigInteger getNonce(String address) throws Exception {

EthGetTransactionCount ethGetTransactionCount =
web3j.ethGetTransactionCount(address, DefaultBlockParameterName.LATEST)
.sendAsync()
.get();
return ethGetTransactionCount.getTransactionCount();
}
}

summary

  1. The call of read-only contract is call Method , This method does not require private key signature , Just know the address and method of the contract ( Method name , Enter the reference 、 The ginseng ) that will do .
  2. payment gas And the belt value Call to , All need the signature of the account private key , There are three steps :encode( Method code )、sign ( Sign method )、send( Send signed transactions ).
  3. Whether it's js and java, The calling process is consistent , In essence, they all pass through the Ethereum node json-rpc call

The contract etherscan Address

Reference documents

web3.js Chinese document
web3j English document
web3h Chinese document

If there is any error in the above content, please leave a message to discuss .

Add :

web3j The call returns the type of multiple address parameters

A little friend asked me , The value returned by the contract is an address array .
as follows , This is my example

 @Test
public void callContractTransaction() throws Exception {

Function function = new Function(
"getComponents",
Collections.EMPTY_LIST,
Arrays.asList(new TypeReference<DynamicArray<Address>>(){
}));
String encodedFunction = FunctionEncoder.encode(function);
org.web3j.protocol.core.methods.response.EthCall response = web3j.ethCall(
Transaction.createEthCallTransaction(null, contractAddress, encodedFunction),
DefaultBlockParameterName.LATEST)
.sendAsync().get();
Assert.isNull(response.getError(),"callContractTransaction error");
List<Type> results = FunctionReturnDecoder.decode(response.getValue(), function.getOutputParameters());
for (Type result : results) {

System.out.println(result.getValue());
}
}
版权声明:本文为[Big tail]所创,转载请带上原文链接,感谢。 https://netfreeman.com/2022/04/202204040602306036.html