Web3j: Error de "Gas intrínseco demasiado bajo" al implementar un contrato en Ethereum desde Java

Soy nuevo en Ethereum y Blockchain, he estado intentando la ejecución de Contratos usando Metamask y Remix usando el navegador Chrome durante algún tiempo.

Estoy tratando de implementar el mismo contrato desde Java usando Web3j.

Pero cuando trato de ejecutar mi contrato, recibo el siguiente errorIntrinsic gas too low

Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.RuntimeException: Error processing transaction request: Intrinsic gas too low
    at java.util.concurrent.CompletableFuture.reportGet(Unknown Source)
    at java.util.concurrent.CompletableFuture.get(Unknown Source)
    at com.solartis.bc.Sample.main(Sample.java:44)
Caused by: java.lang.RuntimeException: Error processing transaction request: Intrinsic gas too low
    at org.web3j.tx.ManagedTransaction.send(ManagedTransaction.java:43)
    at org.web3j.tx.Contract.lambda$deployAsync$24(Contract.java:288)...

He leído algunas otras preguntas para aumentar el valor de "Gas", pero no importa cuánto valor más alto dé, sigo recibiendo el mismo error.

¿Alguien más ha enfrentado el mismo problema? No estoy seguro de lo que estoy haciendo mal. Adjunto más detalles a continuación

ContractRunner.java

package com.solartis.bc;

public class ContractRunner {

    public static void main(String args[]) throws InterruptedException, ExecutionException, IOException, CipherException, TransactionTimeoutException {
        Web3j web3 = Web3j.build(new HttpService("http://xxxxxxx.westus.cloudapp.azure.com:8545/"));  // defaults to http://localhost:8545/
        Web3ClientVersion web3ClientVersion = web3.web3ClientVersion().sendAsync().get();
        String clientVersion = web3ClientVersion.getWeb3ClientVersion();
        System.out.println(clientVersion);
        Credentials credentials = WalletUtils.loadCredentials("Mxxxxxxxxe", "C:\\Users\\adheep_m\\AppData\\Roaming\\Ethereum\\keystore\\UTC--2017-07-07T13-52-18.006069200Z--3b0d3fa08f0e0b3da8fe1f8ac0e05861bfdada25");
        System.out.println(credentials.getAddress());

        BigInteger GAS = new BigInteger("30000000");
        BigInteger GAS_PRICE = new BigInteger("20");
        BigInteger ETH = new BigInteger("1");
        //LeisureTravelPolicyHolder contract = LeisureTravelPolicyHolder.deploy(web3,credentials,GAS,GAS_PRICE,ETH,test,test,test,test,test,test,test,test,test).get();

        Token con = Token.deploy(web3,credentials,GAS,GAS_PRICE,ETH).get();
        System.out.println(con.getContractAddress());
    }
}

token.sol

pragma solidity ^0.4.0;

contract Token {
 mapping (address => uint) public balances;

 function Token() {
     balances[msg.sender] = 1000000;
 }

 function transfer(address _to, uint _amount) {
     if (balances[msg.sender] < _amount) {
         throw;
     }

     balances[msg.sender] -= _amount;
     balances[_to] += _amount;
 }
}

Token.java

package com.solartis.bc;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.Future;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Address;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.datatypes.generated.Uint256;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.tx.Contract;
import org.web3j.tx.TransactionManager;

/**
 * Auto generated code.<br>
 * <strong>Do not modify!</strong><br>
 * Please use {@link org.web3j.codegen.SolidityFunctionWrapperGenerator} to update.
 *
 * <p>Generated with web3j version 2.2.1.
 */
public final class Token extends Contract {
    private static final String BINARY = "6060604052341561000f57600080fd5b5b600160a060020a0333166000908152602081905260409020620f424090555b5b6101678061003f6000396000f300606060405263ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166327e235e38114610048578063a9059cbb14610086575b600080fd5b341561005357600080fd5b61007473ffffffffffffffffffffffffffffffffffffffff600435166100b7565b60405190815260200160405180910390f35b341561009157600080fd5b6100b573ffffffffffffffffffffffffffffffffffffffff600435166024356100c9565b005b60006020819052908152604090205481565b73ffffffffffffffffffffffffffffffffffffffff3316600090815260208190526040902054819010156100fc57600080fd5b73ffffffffffffffffffffffffffffffffffffffff338116600090815260208190526040808220805485900390559184168152208054820190555b50505600a165627a7a7230582081fd33c821a86127abf00c9fafe2e14e4db6279ab9dd788e3ad3597d2280b6cf0029";

    private Token(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
        super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit);
    }

    private Token(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
        super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit);
    }

    public Future<Uint256> balances(Address param0) {
        Function function = new Function("balances", 
                Arrays.<Type>asList(param0), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
        return executeCallSingleValueReturnAsync(function);
    }

    public Future<TransactionReceipt> transfer(Address _to, Uint256 _amount) {
        Function function = new Function("transfer", Arrays.<Type>asList(_to, _amount), Collections.<TypeReference<?>>emptyList());
        return executeTransactionAsync(function);
    }

    public static Future<Token> deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialWeiValue) {
        return deployAsync(Token.class, web3j, credentials, gasPrice, gasLimit, BINARY, "", initialWeiValue);
    }

    public static Future<Token> deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialWeiValue) {
        return deployAsync(Token.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, "", initialWeiValue);
    }

    public static Token load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
        return new Token(contractAddress, web3j, credentials, gasPrice, gasLimit);
    }

    public static Token load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
        return new Token(contractAddress, web3j, transactionManager, gasPrice, gasLimit);
    }
}

Respuestas (2)

Me di cuenta de lo que estaba mal. Mis valores de GAS_PRICE y GAS_LIMIT no eran correctos. Más tarde descubrí que Web3j tiene GAS_PRICE y GAS_LIMIT predeterminados, vea el código actualizado a continuación

        BigInteger GAS = Contract.GAS_LIMIT;
        BigInteger GAS_PRICE = Contract.GAS_PRICE;

Contract.GAS_LIMITy Contract.GAS_PRICEestán en desuso . Por lo tanto, use las siguientes constantes en org.web3j.tx.gas.DefaultGasProvidersu lugar:

DefaultGasProvider.GAS_PRICE; DefaultGasProvider.GAS_LIMIT;

Me alegro de que lo arregló. Vuelva después de 48 horas y acepte su propia respuesta :-) (Hay un límite de tiempo impuesto... )

Reaccionando a https://ethereum.stackexchange.com/users/12743/adheep-mohamed-abdul-kader

No debes usar:

Contract.GAS_LIMIT

ya que está en desuso:

public abstract class Contract extends ManagedTransaction {

    // https://www.reddit.com/r/ethereum/comments/5g8ia6/attention_miners_we_recommend_raising_gas_limit/
    /**
     * @deprecated ...
     * @see org.web3j.tx.gas.DefaultGasProvider
     */
    public static final BigInteger GAS_LIMIT = BigInteger.valueOf(4_300_000);

pero usa:

DefaultGasProvider.GAS_LIMIT
DefaultGasProvider.GAS_PRICE

o solo de DefaultGasProviderinmediato

saludos