Solidity, Visualizing [object object] when checking wallet address with hardhat, ethers.js - solidity

I'm having this issue when testing this lines of code:
it("Subscribes multiple deployers", async function () {
const additionalEntrances = 3
const startingIndex = 0
const accounts = await ethers.getSigners()
for (let i = startingIndex; i < startingIndex + additionalEntrances; i++) {
MarketOrder = MarketOrder.connect(accounts[i])
await MarketOrder.Deposit(ArraySL[i], { value: ArrayValue[i] })
console.log(`Account: ${accounts[i].toString()} Value: ${ArrayValue[i]} SL: ${ArraySL[i]}`)
}
})
And this is how it shows in the console
Account: [object Object] Value: 5000000000000000000 SL: 1200
Account: [object Object] Value: 10000000000000000000 SL: 1502
Account: [object Object] Value: 20000000000000000000 SL: 1960
How can I visualize wallet address properly?

const accounts = await ethers.getSigners()
Each element of the accounts array is an instance of the ethers.js Wallet object.
And Javascript casts any object (that doesn't override the toString() method) to string as [object Object].
If you want to print an address of the wallet, you can use its address property:
console.log(`Account: ${accounts[i].address}`)

Related

Some contract functions runs on hardhat network While others don't

I Got following error while testing my contract
$ npx hardhat test
NftyplayLicense
buyLicense
done!
1) should buy the license successfully
0 passing (2s)
1 failing
1) NftyplayLicense
buyLicense
should buy the license successfully:
Error: invalid address or ENS name (argument="name", value=undefined, code=INVALID_ARGUMENT, version=contracts/5.7.0)
at Logger.makeError (node_modules/#ethersproject/logger/src.ts/index.ts:269:28)
at Logger.throwError (node_modules/#ethersproject/logger/src.ts/index.ts:281:20)
at Logger.throwArgumentError (node_modules/#ethersproject/logger/src.ts/index.ts:285:21)
at /home/bhavesh/Documents/boilerplate/node_modules/#ethersproject/contracts/src.ts/index.ts:123:16
at step (node_modules/#ethersproject/contracts/lib/index.js:48:23)
at Object.next (node_modules/#ethersproject/contracts/lib/index.js:29:53)
at fulfilled (node_modules/#ethersproject/contracts/lib/index.js:20:58)
at processTicksAndRejections (node:internal/process/task_queues:95:5)
Following is the Test that I have written
const { assert, expect } = require("chai")
const { network, ethers, deployments } = require("hardhat")
const { developmentChains } = require("../helper-hardhat-config")
!developmentChains.includes(network.name)
? describe.skip()
: describe("NftyplayLicense", function () {
let nftyplayLicenseContract, nftyPlayLicense, deployer, player, param
beforeEach(async function () {
const accounts = await ethers.getSigners()
deployer = accounts[0]
player = accounts[1]
await deployments.fixture(["all"])
nftyplayLicenseContract = await ethers.getContract("NftyPlayLicensing")
nftyPlayLicense = nftyplayLicenseContract.connect(deployer)
param = {
name: "NftyPlayLicensing",
category: "1",
durationInDays: "1",
licenseType: "1",
nftAddress: "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC",
nonce: 735,
price: "1000000000000000000",
r: "0xb07df588e0674bc28050a58a7f2cfd315f7e0aec136d0ebcf89fdcd9fa8aa928",
s: "0x109a8b6ff70709d2fecdba8b385097f2f979738518e4c444d4cf95b7e2c9621b",
signer: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
tokenId: "1",
v: 27,
}
})
describe("buyLicense", function () {
it("should buy the license successfully", async function () {
nftyPlayLicense.whitelist("0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC")
console.log("done!")
nftyPlayLicense = nftyplayLicenseContract.connect(player)
await expect(
nftyPlayLicense.buyLicense(param, "https://uri.com", {
value: ethers.utils.parseEther("1"),
})
).to.emit("NftyPlayLicensing", "LicenseBought")
const result = await nftyPlayLicense.getExecutedOrder(735)
assert.equal(result, true)
})
})
})
Note that
nftyPlayLicense.whitelist("0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC")
is running fine, not not in case of
nftyPlayLicense.buyLicense(param, "https://uri.com", {
value: ethers.utils.parseEther("1"),
})
I've made order and signature object by metamask and stored it locally and then using that i am calling buyLicense function from contract using that object as params.
this is my contract function:
function buyLicense(OrderTypes.LicenseOrder calldata order, string memory uri) public payable {
require(isOrderExecuted[order.nonce] == false, "Order is already Executed");
require(isCancelled[order.signer][order.nonce] == false, "Listing is Cancelled");
bytes32 orderHash = SignatureVerifier.hashMakerOrder(order, ORDER_TYPE_HASH);
validateMakerOrder(order, orderHash);
uint256 licenseTokenId = mintLicenseToken(msg.sender, uri, order);
isOrderExecuted[order.nonce] = true;
emit LicenseBought(
licenseTokenId,
order.price,
order.category,
order.tokenId,
order.signer,
order.licenseType,
order.nftContract
);
}
But I am unable to run that function

Error: invalid address (argument="address", value=undefined, code=INVALID_ARGUMENT, version=address/5.1.0)

I'm Getting this error when trying to deploy a smart contract with a function:
Error: invalid address (argument="address", value=undefined, code=INVALID_ARGUMENT, version=address/5.1.0) (argument="tokenAddress", value=undefined, code=INVALID_ARGUMENT, version=abi/5.0.7)
Here is my code:
const handlePresale = async (e) => {
e.preventDefault();
const web3 = await getWeb3();
const abiData = SafeHubPresaleAbi;
const contractAddress = "0x4498F943E0a13D70B28e7565CF4E33bF443e6Bf9";
const duration = {
seconds: function (val) {
return val;
},
minutes: function (val) {
return val * this.seconds(60);
},
hours: function (val) {
return val * this.minutes(60);
},
days: function (val) {
return val * this.hours(24);
},
weeks: function (val) {
return val * this.days(7);
},
years: function (val) {
return val * this.days(365);
},
};
const latestTime = new Date().getTime();
const openingTime = latestTime + duration.minutes(1);
const closingTime = openingTime + duration.minutes(10);
const liqAddingTime = closingTime + duration.minutes(5);
let _info = {
address : "0x4498F943E0a13D70B28e7565CF4E33bF443e6Bf9",
tokenPrice : web3.utils.toWei("10", "ether"),
hardCap: web3.utils.toWei("100", "ether"),
softCap: web3.utils.toWei("30", "ether"),
minInv: web3.utils.toWei("0.1", "ether"),
maxInv: web3.utils.toWei("5", "ether"),
openingTime: openingTime,
closingTime: closingTime,
};
let _uniInfo = {
listingPrice: web3.utils.toWei("20", "ether"),
liqTime: liqAddingTime,
lockTime: 365,
precentLock: 25,
};
let _stringInfo = {
listingName: "WER sale",
};
const preslaeContract = await new web3.eth.Contract(
abiData,
contractAddress
);
// console.log(preslaeContract.methods)
preslaeContract.methods
.createPresale(_info,_uniInfo,_stringInfo)
.call((err, result) => {
console.log(result), console.log(err);
});
}
Solidity constructor:
constructor(address _safuFactoryAddress, address _safuDevAddress) public {
require(_safuFactoryAddress != address(0));
require(_safuDevAddress != address(0));
safuFactoryAddress = payable(_safuFactoryAddress);
safuDevAddress = payable(_safuDevAddress);
}
since there are still no answers yet, but over 1k views though, I'll leave here a solution if anyone else is facing the same error.
The solidity constructor in your example expects 2 arguments of type address. This means if you deploy your contract you also need to provide those 2.
As for the deployment:
No matter how you deploy your contract, providing all constructor arguments should solve your problem and your contract should be able to get deployed now.
If you work with truffle, you need to adjust your deployer .../migrations/2_deploy_contracts.js and pass 2 addresses to satisfy the constructor parameters.
var SafeHubPresale = artifacts.require("./SafeHubPresale.sol");
module.exports = function(deployer) {
deployer.deploy(SafeHubPresale, [address1], [address2]);
};
The same applies for test:
let's say:
var myContract = await SafeHubPresale.new(accounts[1], accounts[2], {from: accounts[0], gas: 0});
For those in Remix, select the drop down next to "deploy" and you will need to provide a "to" & "from" address for this to work
In your smart contract, more than one argument may present and cannot fulfill its value when you deploy. When you deploy you take these values and call deploy() it's working correctly.
In your constructor
constructor(address _safuFactoryAddress, address _safuDevAddress)
more than one address value present there you may not provide this value when you deploy.

How to count the number of elements in this particular object

I am making a call to an API and the response is somehow what I expect. However, I want to count the number of elements returned and I can not do it. This is what I think is important from the code.
Call in Vue component
data(){
return {
messages: {}
}
},
loadMessages(){
axios.get("api/messagesmenu")
.then((data) => { this.messages = data.data})
}
Api controller
public function index(){
$messages = Message::all()->where('read_at', NULL);
if(isset($messages)){
foreach($messages as $message){
$from = User::find($message->from_id);
$message->fromPrenom = $from->first_name;
$message->fromNom = $from->last_name;
$message->fromImage = $from->user_image;
}
}else{
$messages = [];
}
return $messages;
}
Type of response from the API
{"3":{"id":560,"from_id":2,"to_id":1,"content":"tgr","created_at":"2019-07-15 16:59:03","read_at":null,"fromPrenom":"abdel1","fromNom":"Hidalgo","fromImage":"user2-160x160.png"}}
I want to count the number of objects I obtain. if (in vue component) I do
this.messages.length
it returns undefined
Try this:
const messages = {"3":{"id":560,"from_id":2,"to_id":1,"content":"tgr","created_at":"2019-07-15 16:59:03","read_at":null,"fromPrenom":"abdel1","fromNom":"Hidalgo","fromImage":"user2-160x160.png"}}
console.log(Object.keys(messages).length) // 1
Or in your code:
...
.then((data) => {
this.messages = data.data
console.log(Object.keys(this.messages).length)
})

Web3 | TransferFrom() transactions always Failed

I'm trying to send Custom ERC20 Token to Owner Wallet Address using transferFrom() function using Web3.js
However all the Transactions are failed. Which is the same problem occur on Remix IDE.
Some answers on stackOverflow here says that the approve() is needed to call first before the transferFrom() function. so, I tried on Remix frist but I got the same problem. And then tried with using Web3.js like below.
const myContract = new web3.eth.Contract(abi);
const amount = sendAmount;
let address = myAddress;
myContract.options.address = contractAddress;
myContract.options.from = TokenOwner;
let options = myContract.options;
let data1 = myContract.methods.approve(address, amount).encodeABI();
let data2 = myContract.methods.transferFrom(address, TokenOwner, amount).encodeABI();
const ethAccount = fromPrivateKey(toBuffer("0x..."));
const fromPrivateKeyBuffer = ethAccount.getPrivateKey();
web3.eth.getTransactionCount(TokenOwner, (err, count) => {
if (err) return;
const txData = {
chainId: 0x03,
gasPrice: web3.utils.toHex(42000000000),
gasLimit: web3.utils.toHex(90000),
to: contractAddress,
from: TokenOwner,
value: 0x0,
nonce: web3.utils.toHex(count),
data: data1
};
const tx = new ethTx(txData);
tx.sign(fromPrivateKeyBuffer);
const serializedTx = tx.serialize().toString("hex");
if (!serializedTx) {
return;
} else {
web3.eth.sendSignedTransaction(`0x${serializedTx}`, (err, MuiTXHash) => {
console.log("err : ", err, "Data1-MuiTXHash : ", MuiTXHash);
// START DATA2
web3.eth.getTransactionCount(TokenOwner, (err, count) => {
if (err) return;
const txData2 = {
chainId: 0x03,
gasPrice: web3.utils.toHex(42000000000),
gasLimit: web3.utils.toHex(90000),
to: contarctAddress,
from: TokenOwner,
value: 0x0,
nonce: web3.utils.toHex(count + 1),
data: data2
};
const tx2 = new ethTx(txData2);
tx2.sign(fromPrivateKeyBuffer);
const serializedTx2 = tx2.serialize().toString("hex");
if (!serializedTx2) {
return;
} else {
web3.eth.sendSignedTransaction(`0x${serializedTx2}`, (err, MuiTXHash2) => {
console.log("err : ", err, "Data2-MuiTXHash : ", MuiTXHash2);
});
}
});
// END DATA2
});
}
});
};
I got the two Transaction Hash return data and the TransferFrom() transaction is failed again.
What is the problem?
How can I make it success? I have to withdraw the custom ERC20 token from specific address to owner. so I have to use transferFrom() transaction.
Please let me know how to do. Thanks.
I guess the compiling on Remix had some errors so I created new solidity file with same code on it and deployed it. The new smart contract worked well and no errors occurred. The errors was not about my code. If someone's suffering like this problems, then create a new contract address and I don't recommend using 'At Address' on Remix. This is not work properly at all.
I was tried appove() + transferFrom () , allowance() on Solidity working well but on web3 not working error same as you
I guess the transferFrom function should be called by the spender (i.e the address to which the TokenOwner has approved to spend). So,
const txData2 = {
chainId: 0x03,
gasPrice: web3.utils.toHex(42000000000),
gasLimit: web3.utils.toHex(90000),
to: contarctAddress,
from: address, // spender's address
value: 0x0,
nonce: web3.utils.toHex(count + 1),
data: data2
};
And don't forget to use spender's privateKey to sign the txn and spender's address in getTransactionCount
Read Here : Ethereum Wiki
Hope it helps. :)

Win 8 Apps : saving and retrieving data in roamingfolder

I'm trying to store few user data into a roamingFolder method/property of Windows Storage in an app using JavaScript. I'm following a sample code from the Dev Center, but no success. My code snippet is as follows : (OR SkyDrive link for the full project : https://skydrive.live.com/redir?resid=F4CAEFCD620982EB!105&authkey=!AE-ziM-BLJuYj7A )
filesReadCounter: function() {
roamingFolder.getFileAsync(filename)
.then(function (filename) {
return Windows.Storage.FileIO.readTextAsync(filename);
}).done(function (data) {
var dataToRead = JSON.parse(data);
var dataNumber = dataToRead.count;
var message = "Your Saved Conversions";
//for (var i = 0; i < dataNumber; i++) {
message += dataToRead.result;
document.getElementById("savedOutput1").innerText = message;
//}
//counter = parseInt(text);
//document.getElementById("savedOutput2").innerText = dataToRead.counter;
}, function () {
// getFileAsync or readTextAsync failed.
//document.getElementById("savedOutput2").innerText = "Counter: <not found>";
});
},
filesDisplayOutput: function () {
this.filesReadCounter();
}
I'm calling filesDisplayOutput function inside ready method of navigator template's item.js file, to retrieve last session's data. But it always shows blank. I want to save upto 5 data a user may need to save.
I had some trouble running your code as is, but that's tangential to the question. Bottom line, you're not actually reading the file. Note this code, there's no then or done to execute when the promise is fulfilled.
return Windows.Storage.FileIO.readTextAsync(filename);
I hacked this in your example solution and it's working... typical caveats of this is not production code :)
filesReadCounter: function () {
roamingFolder.getFileAsync(filename).then(
function (filename) {
Windows.Storage.FileIO.readTextAsync(filename).done(
function (data) {
var dataToRead = JSON.parse(data);
var dataNumber = dataToRead.count;
var message = "Your Saved Conversions";
//for (var i = 0; i < dataNumber; i++) {
message += dataToRead.result;
document.getElementById("savedOutput1").innerText = message;
//}
//counter = parseInt(text);
//document.getElementById("savedOutput2").innerText = dataToRead.counter;
}, function () {
// readTextAsync failed.
//document.getElementById("savedOutput2").innerText = "Counter: <not found>";
});
},
function () {
// getFileAsync failed
})
},