Nethereum // Infura/RPCclientes

Me está costando mucho conseguir que las transacciones se publiquen en la red principal. El problema no está relacionado con el saldo de mi billetera ni con la gasolina. Una búsqueda de saldo en el mismo contrato funciona correctamente. Sin embargo, no puedo obtener esta transacción firmada fuera de línea (equivalente de transacción sin procesar)

Probé todas las formas de pasar varios parámetros, configuré el Gas/Precio predeterminado a través del administrador de transacciones y utilicé el método SendTransactionAsync() con las sobrecargas que no las requieren. He enviado el método con los parámetros del contrato individualmente (no en una matriz de objetos como se muestra a continuación). Verifiqué dos veces el nonce: aparece como 0. Intenté esto y la variante andwaitforreceipt.

var contract = web3.Eth.GetContract(contractAbi,contractAddress);
var function = contract.GetFunction("transfer");
hash = await function.SendTransactionAsync(@from: accountAddress, gas: new HexBigInteger(60000),
       gasPrice: HexBigInteger(40), value: null, functionInput: new object[] {  recipient, Web3.Convert.ToWei(value) });

El contrato es un token ERC20 estándar. ¿Alguna idea de por qué la transacción no devuelve errores, sin embargo, Infura no transmite? Usé este mismo código muchas veces con un nodo geth privado normal.

Editar: también he estado tratando de obtener algunas de las otras API RPC JSON. Si alguien está familiarizado, ¿confirmaría que esta es la forma correcta de hacerlo enviando la carga útil de datos? Recibo un "error subvaluado" de la API de etherscan

        var contract = web3.Eth.GetContract(contractAbi, contractAddress);
        var function = contract.GetFunction("transfer");
        string fdata = function.GetData(new object[] { recipient, Web3.Convert.ToWei(value) });
        var txCount = await web3.Eth.Transactions.GetTransactionCount.SendRequestAsync(accountAddress);

        var encoded = Web3.OfflineTransactionSigner.SignTransaction(privateKey: accountKey, to: contractAddress, amount: 0, nonce: txCount.Value, gasPrice: new BigInteger(70), gasLimit: new HexBigInteger(60000), data: fdata);
        encoded = "0x" + encoded;

Respuestas (1)

Puedo ver que el precio que está utilizando ya es bastante bajo (debe convertirse de Gwei a Wei), pero también se beneficiará de estimar el gas de la transacción y usar otras funciones de Nethereum.

En primer lugar, solo podemos tener una TransferFunction. Este es principalmente un objeto que describe la función de transferencia del contrato ERC20 y los diferentes parámetros. Esto hereda de ContractMessage, que incluye otras propiedades como AddressFrom, Gas, GasPrice, Value (valor de éter) que forman parte de una transacción normal.

[Function("transfer", "bool")]
public class TransferFunction : ContractMessage
{
    [Parameter("address", "_to", 1)]
    public string To { get; set; }

    [Parameter("uint256", "_value", 2)]
    public BigInteger TokenAmount { get; set; }
}

Ahora definamos nuestras variables personalizadas:

var senderAddress = "0x12890d2cce102216644c59daE5baed380d84830c";
var receiverAddress = "0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe";
var privatekey = "0xb5b1870957d373ef0eeffecc6e4812c0fd08f554b37b233526acc331bf1544f7";
var url = "https://rinkeby.infura.io/";

y crea una nueva instancia de Web3.

var web3 =  new Web3.Web3(new Account(privatekey), url);

Esta instancia de Web3 se ha creado usando un nuevo objeto de Cuenta usando la clave privada. Esto permite principalmente que Web3 firme cualquier transacción "fuera de línea" antes de enviarla, por lo que no es necesario que elabore todo usted mismo.

El siguiente paso es crear una instancia del mensaje que vamos a enviar.

var transactionMessage = new TransferFunction()
            {
                FromAddress = senderAddress,
                To = receiverAddress,
                TokenAmount = 100,
                //Set our own price
                GasPrice =  Web3.Web3.Convert.ToWei(25, UnitConversion.EthUnit.Gwei)

            };

Aquí se ha rellenado FromAddress (esto no es necesario ya que se seleccionará de la Cuenta ya configurada), el receptor (To) del contrato inteligente, el monto y finalmente el GasPrice.

Este GasPrice es un precio personalizado (que no usa el valor predeterminado de Nethereum, que podría ser demasiado costoso debido a la fluctuación de precios, y ahora lo es).

Para establecer el precio, lo hemos convertido de Gwei, que es la unidad que normalmente se usa para fijar el precio, a Wei.

Ahora que tenemos listo nuestro "mensaje" / transacción, podemos crear un controlador de transacciones, que será responsable de enviar la transacción.

var transferHandler = web3.Eth.GetContractTransactionHandler<TransferFunction>();

Otro paso (que es opcional) ya que esto se hace automáticamente por usted es estimar el costo (en gasolina) de la transacción.

var estimate = await transferHandler.EstimateGasAsync(transactionMessage, ContractAddress);
transactionMessage.Gas = estimate.Value;

Y finalmente enviar la transacción:

var transactionHash = await transferHandler.SendRequestAsync(transactionMessage, ContractAddress);

Puede encontrar la muestra completa aquí: https://github.com/Nethereum/Nethereum.CQS.SimpleTokenTransfer/blob/master/Nethereum.CQS.SimpleTokenTransfer/Program.cs#L111-L155