我正在尝试使用javascript将一堆数据写入我的智能合约中,我需要等到所有数据都成功写入合约后,才能通过从合约中调用另一个函数来调用处理这些数据。我了解此步骤是异步的,因此我决定使用promise。但是,我很难理解它是如何工作的。有人可以解释一下.on,.on,.then做什么吗?
我要粘贴整个脚本。该脚本的作用是处理包含地址和值的CSV,并将这些数据发送到我的合同,然后我将调用airDrop()函数,要求合同将正确数量的令牌发送到正确的地址。因此,基本上,这是一个令牌空投脚本。到目前为止,我已经能够成功处理CSV文件,但是没有运气来解决异步部分。
const csv = require("fast-csv");
const web3 = require("./web3");
const addressCap = 200;
var index = 0;
const compiledContract = require("./build/alexAirDrop.json");
const contractAbi = compiledContract.interface;
/* Code below will set up web3.
If a metamask or other ether wallet is not detected,
it will connects to a local host
*/
/*The function below is the main function that will
read the csv file in designated location "./data/airdrop.csv"
and process it to a Javascript Object
*/
async function config() {
var addressLocation = new Object();
var addressList = [];
// console.log("web3:" , web3)
console.log(
"-------------------START IMPORTING CSV FILE-------------------------",
"\n",
"---------------PLEASE IGNORE THE DEPRECATED WARNING!----------------"
);
csv
.fromPath("./data/airdrop.csv", { headers: false })
.on("data", function(data) {
if (
index < addressCap && //These four lines of code verify if addresses in csv file are valid
web3.utils.isAddress(data[0]) &&
data[0] !== null &&
data[0] !== ""
) {
if (data[0] in addressLocation) {
//This line of code checks if a beneficiary already exist in addressLocation
var was_balance = parseInt(addressLocation[data[0]]); //If exist, simply topup the value of that particular beneficiary
addressLocation[data[0]] = data[1] + was_balance;
index++;
} else {
//If the beneficiary does not exist in addressLocation Object, it will be added to the Object and assign it a value.
addressLocation[data[0]] = data[1].toString();
addressList.push(data[0]);
index++;
}
} else {
if (data[0] !== "") {
console.log("ERROR:", data[0], "is invalid");
}
}
})
.on("end", async function() {
console.log("------------------------DONE!------------------------");
var totalValue = 0;
Object.keys(addressLocation).forEach(key => {
totalValue = parseInt(addressLocation[key]) + parseInt(totalValue); //Calculate the total value that needs to be transfered.
});
console.log(
"Benefeciaries are listed HERE:",
"\n",
addressLocation, //Print out addressLocation Object
"\n",
"Total beneficiaries are:",
Object.keys(addressLocation).length, //Print out the length of addressLocation
"\n",
"Airdrop total: ",
parseInt(totalValue) //Print out the total value that needs to be transfered.
);
/*The following code will create a new instance of a depolyed Airdrop contract
NOTE!!!!!!!! Every time you alter the contract(Even one single splace), you need to
re-compile the entire contract on Remix using Solidity Compiler V0.4.23commit. Then
deploy the contract, copy and paste the abi of the contract(Can be retrieved through Remix)
to the variable contractAbi. Copy and paste the address of the contract in the following code
where the comment says //ADDRESS!!!!
*/
const instance = web3.eth.Contract(
JSON.parse(contractAbi),
"0x280becafd14f7be440205524827c35063e1eb5e0" //ADDRESS!!!!
);
// Get accounts information
const accounts = await web3.eth.getAccounts();
console.log("ACCOUNTS: ", accounts);
const userAccount = accounts[0];
console.log("Coinbase :", userAccount); //This line will show you the first account in accounts.
const p0 = [];
Object.keys(addressLocation).forEach(keys => {
p0.push(
instance.methods
.addingBeneficiaries(keys, addressLocation[keys])
.send({
from: userAccount,
gas: 1000000
})
);
});
console.log(p0)
Promise.all(p0)
.then(()=> {
const p1 = [];
Object.keys(addressLocation).forEach(keys => {
console.log("SENDING TRANSACTION TO: ", keys)
p1.push(
instance.methods.airDrop(keys).send({
from: userAccount,
gas: 1000000
})
);
});
Promise.all(p1)
.then(values => {
console.log("value1: ", values);
})
.catch(errors => {
console.log("error1: ", errors);
});
})
.catch(errors => {
console.log("e0: " + errors);
});
console.log("ADDING BENEFICIARIES COMPLETED");
预期:
将所有地址和值发送到智能合约后,airDrop()函数应运行。
实际:
该代码在Promise.all(p0)
之后停止工作。