Quiero crear y firmar una transacción en el navegador usando web3. Para crear una transacción sin procesar, creo que tengo que hacer algo como esto (espero que puedas llenar los vacíos de mi conocimiento)
var pk = '0x6ba33b3f7997c2bf63d82f3baa1a8069014a59fa1f554af3266aa85afee9d0a9';
pk = new Buffer(pk,'hex');
var address = '0xFb4d271F3056aAF8Bcf8aeB00b5cb4B6C02c7368';
var myContractsAddress = '0x0cb4edc28d17c43a75797bf5effc141fd5da8715';
var rawTx = {
nonce: web3.toHex(web3.eth.getTransactionCount(acct1)),
to: myContractsAddress,
gasPrice: web3.toHex(20000000000),
gasLimit: web3.toHex(200000),
value: ***Here I am not sure, am I supposed to encode my list of variables? and do I encode everything to hex, or just integers? And how would that list look like?***
data: *This field is irrelevant for now, and just for documentationpurpose, right?*
}
Esto debería darme mi transacción sin procesar (¡la parte sobre el campo de datos que desafortunadamente no conozco y me encantaría recibir ayuda!
Digamos que mi transacción sin procesar es válida y correcta en este punto, tendría que firmarla con la clave privada ahora. La solución que he visto usaba una biblioteca node.js llamada ethereumjs-tx . ¿Hay una solución solo con web3, o tengo que portar esta biblioteca de alguna manera a mi navegador?
A continuación se muestra el código de trabajo que llama "incremento" en https://programtheblockchain.com/dapps/counter . (Más información sobre esa muestra aquí: https://programtheblockchain.com/posts/2017/12/13/building-decentralized-apps-with-ethereum-and-javascript/ ).
Utiliza web3.js
y ethereumjs-tx
:
<!-- from https://github.com/ethereumjs/browser-builds/raw/master/dist/ethereumjs-tx/ethereumjs-tx-1.3.3.min.js -->
<script src="ethereumjs-tx-1.3.3.min.js"></script>
<script>
var address = "0xf15090c01bec877a122b567e5552504e5fd22b79";
var abi = [{"constant":true,"inputs":[],"name":"getCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"increment","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_count","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}];
var account = "<REDACTED ACCOUNT ADDRESS>";
var privateKey = "<REDACTED PRIVATE KEY WITHOUT 0x PREFIX>";
var web3 = new Web3(new Web3.providers.HttpProvider(
"https://ropsten.infura.io/<REDACTED API KEY"));
web3.eth.getTransactionCount(account, function (err, nonce) {
var data = web3.eth.contract(abi).at(address).increment.getData();
var tx = new ethereumjs.Tx({
nonce: nonce,
gasPrice: web3.toHex(web3.toWei('20', 'gwei')),
gasLimit: 100000,
to: address,
value: 0,
data: data,
});
tx.sign(ethereumjs.Buffer.Buffer.from(privateKey, 'hex'));
var raw = '0x' + tx.serialize().toString('hex');
web3.eth.sendRawTransaction(raw, function (err, transactionHash) {
console.log(transactionHash);
});
});
</script>
getData
:...increment.getData("foo", 32);
Usando Web3.js 1.0.0
encoded = contractInstance.methods.myMethod(params).encodeABI()
var tx = {
to : myContractAddress,
data : encoded
}
web3.eth.accounts.signTransaction(tx, privateKey).then(signed => {
web3.eth.sendSignedTransaction(signed.rawTransaction).on('receipt', console.log)
});
myMethod
?nonce
, gasPrice
, gasLimit
, etc?tx
objeto también debe incluir nonce
, gasPrice
, gasLimit
, value
y chainId
. Estos normalmente serían inferidos por web3, pero si desea mantener las claves en otro lugar y firmar usando algo como eth-lightwallet
, eso es lo que su tx
objeto debe tener configurado.Estuve perdido en este misterio durante algún tiempo y terminé escribiendo un paquete para resolverlo. Es web3js-raw, que es un contenedor simple alrededor de web3.js. Se puede encontrar una muestra completamente funcional usando esto aquí .
Puede usar browserify para empaquetar todo en un solo archivo .js y ejecutarlo en el navegador. El ejemplo anterior también explica cómo usar browserify.
Existe una forma mejor y más sencilla de firmar y ejecutar la función de contrato inteligente. Aquí su función es addBonus.
En primer lugar, crearemos la instancia de contrato inteligente:
const createInstance = () => {
const bscProvider = new Web3(
new Web3.providers.HttpProvider(config.get('bscRpcURL')),
);
const web3BSC = new Web3(bscProvider);
const transactionContractInstance = new web3BSC.eth.Contract(
transactionSmartContractABI,
transactionSmartContractAddress,
);
return { web3BSC, transactionContractInstance };
};
Ahora crearemos una nueva función para iniciar sesión y ejecutar la función addBonus
const updateSmartContract = async (//parameters you need) => {
try {
const contractInstance = createInstance();
// need to calculate gas fees for the addBonus
const gasFees =
await contractInstance.transactionContractInstance.methods
.addBonus(
// all the parameters
)
.estimateGas({ from: publicAddress_of_your_desired_wallet });
const tx = {
// this is the address responsible for this transaction
from: chainpalsPlatformAddress,
// target address, this could be a smart contract address
to: transactionSmartContractAddress,
// gas fees for the transaction
gas: gasFees,
// this encodes the ABI of the method and the arguments
data: await contractInstance.transactionContractInstance.methods
.addBonus(
// all the parameters
)
.encodeABI(),
};
// sign the transaction with a private key. It'll return messageHash, v, r, s, rawTransaction, transactionHash
const signPromise =
await contractInstance.web3BSC.eth.accounts.signTransaction(
tx,
config.get('WALLET_PRIVATE_KEY'),
);
// the rawTransaction here is already serialized so you don't need to serialize it again
// Send the signed txn
const sendTxn =
await contractInstance.web3BSC.eth.sendSignedTransaction(
signPromise.rawTransaction,
);
return Promise.resolve(sendTxn);
} catch(error) {
throw error;
}
}
Feliz codificación :)
usuario19510
ethereumjs-tx
no necesita ser "portado" al navegador, ya que ya funciona bien allí. ¿Tiene el ABI para su contrato?value
es la cantidad de éter que está enviando (quizás 0 si solo está llamando a una función de contrato).data
es lo que le dice al contrato qué función está llamando (a través de un hash llamado "selector de función") y con qué parámetros (codificados por ABI). Si tiene el ABI, web3.js puede calcular eldata
campo por usted.S1r_Mar71n
usuario19510
S1r_Mar71n
usuario19510
S1r_Mar71n