In migration file i'm deploying one contract and for that contract i'm passing another contract's address as a constructor parameter
var jbkContract = artifacts.require("./JBK.sol");
var payBContract = artifacts.require("./payback.sol");
var contract_address = '0xB525F2F0046fA37f21EaF1F0619B3de7c1094324';
module.exports = async function(deployer) {
let ins = await jbkContract.at(contract_address);
await deployer.deploy(payBContract,ins,{"from":"0x69A9CAEc73e4378801266dFc796d92aFC98013f6"});
};
For this i'm getting this error
"payback" -- invalid address (arg="_jbkContract", coderType="address", value="[object Object]").
Earlier i was deploying JBKContract and then using that address i was deploying the payback contract and that was working fine.
var jbkContract = artifacts.require("./JBK.sol");
var payBContract = artifacts.require("./payback.sol");
module.exports = async function(deployer) {
deployer.deploy(jbkContract,1000000,"JBK","JBK",{"from":"0x69A9CAEc73e4374401266dFc796d92aFC98013f6"}).then(
function() {
return deployer.deploy(payBContract,jbkContract.address,{"from":"0x69A9CAEc73e4374401266dFc796d92aFC98013f6"});
}
)
};
But i don't want to deploy JBK contract only once and use that contract's address to deploy Payback everytime.How to do that?
I see 2 issues here.
1.0xB525F2F0046fA37f21EaF1F0619B3de7c1094324 is not an address with valid checksum. Address with valid checksum is 0xB525f2f0046Fa37F21Eaf1F0619b3DE7C1094324. This might not be a problem in Truffle though.
2.In the first chunk of code in this line
await deployer.deploy(payBContract, ins, {"from":"0x69A9CAEc73e4378801266dFc796d92aFC98013f6"});
you are passing the contract instance as a parameter instead of contract address. Correct code might be
await deployer.deploy(payBContract, ins.address, {"from":"0x69A9CAEc73e4378801266dFc796d92aFC98013f6"});
Related
I'm studying the Solidity, and I want to understand how to interact with a smartcotnract and etherjs.
I have a simple function like this:
function buyNumber(uint256 _number) public payable {
if(msg.value < 0.1 ether){
revert("more eth!");
}
...todoStuff
}
And I have the test
const tx = {
from: owner.address,
to: myContract.address,
value: ethers.utils.parseEther('0.1'),
data: '0x4b729aff0000000000000000000000000000000000000000000000000000000000000001'
}
let sendTx = await owner.sendTransaction(tx);
console.log(sendTx)
Now, the transaction works because I get 0x4b729aff0000000000000000000000000000000000000000000000000000000000000001 the function signature and parameters with
let iface = new ethers.utils.Interface(ABI)
iface.encodeFunctionData("buyNumber", [ 1 ])
0x4b729aff0000000000000000000000000000000000000000000000000000000000000001
Can I get the same result in easy way? How can I call a function in my contract with params? I could put the msg.value as parameter, but I prefer to use less parameters
You can use the ethers Contract helper class, which allows invoking its methods in a more developer-friedly way, based on the provided contract ABI JSON.
It does the same thing in the background as your script - encodes the function call to the data value.
const contract = new ethers.Contract(contractAddress, abiJson, signerInstance);
// the Solidity function accepts 1 param - a number
// the last param is the `overrides` object - see docs below
await contract.buyNumber(1, {
value: ethers.utils.parseEther('0.1')
});
You can also use the overrides object to specify non-default transaction params. Such as its value (the default value is 0).
I've built a simple smart contract to run on the Ethereum blockchain and I'm trying to replicate some of it's behavior on Solana. After making some slight changes I've managed to compile the program with Solang targeting Solana, but I'm not sure how to go about calling the methods; there doesn't seem to be a great wealth of documentation or examples on this. For example, if my program were written as follows:
contract Example {
function foo(...) { ... }
function bar(...) { ... }
}
How would I specify a call to foo vs a call to bar? Furthermore, how would I encode the arguments for these method calls?
Currently my approach is to use the #solana/buffer-layout library to encode my arguments as a struct, starting with lo.u8('instruction') to specify the method call (in the example case, I assume 0 would refer to foo and 1 would refer to bar). I've taken this approach based on looking at the source code for #solana/spl-token (specifically this file and it's dependencies) but I'm not sure if it will work for a program compiled using Solang, and the buffer layout encoding has been throwing an unexpected error as well:
TypeError: Blob.encode requires (length 32) Uint8Array as src
The code throwing this error is as follows:
const method = lo.struct([
lo.u8('instruction'),
lo.seq(
lo.blob(32),
lo.greedy(lo.blob(32).span),
'publicKeys',
),
])
const data = Buffer.alloc(64); // Using method.span here results in an error, as method.span == -1
method.encode(
{
instruction: 0,
publicKeys: [firstPublicKey, secondPublicKey],
},
data,
);
While this type error seems obvious, it doesn't line up with the sample code in the solana-labs/solana-program-library repository. I'm pretty sure this problem has to do with my use of lo.seq() but I'm not sure what the problem is.
Is my approach to this correct besides this type error, or is my approach fundamentally wrong? How can I call the intended method with encoded arguments? Thank you for any help.
There's a better library for you to use, #solana/solidity, which has a Contract class to encapsulate calls on the contract.
For example, in your case, you could do:
const { Connection, LAMPORTS_PER_SOL, Keypair } = require('#solana/web3.js');
const { Contract, Program } = require('#solana/solidity');
const { readFileSync } = require('fs');
const EXAMPLE_ABI = JSON.parse(readFileSync('./example.abi', 'utf8'));
const PROGRAM_SO = readFileSync('./example.so');
(async function () {
console.log('Connecting to your local Solana node ...');
const connection = new Connection('http://localhost:8899', 'confirmed');
const payer = Keypair.generate();
console.log('Airdropping SOL to a new wallet ...');
const signature = await connection.requestAirdrop(payer.publicKey, LAMPORTS_PER_SOL);
await connection.confirmTransaction(signature, 'confirmed');
const program = Keypair.generate();
const storage = Keypair.generate();
const contract = new Contract(connection, program.publicKey, storage.publicKey, EXAMPLE_ABI, payer);
await contract.load(program, PROGRAM_SO);
console.log('Program deployment finished, deploying the example contract ...');
await contract.deploy('example', [true], program, storage);
const res = await contract.functions.foo();
console.log('foo: ' + res.result);
const res2 = await contract.functions.bar();
console.log('bar: ' + res2.result);
})();
Example adapted from https://github.com/hyperledger-labs/solang#build-for-solana
More information about the package at https://www.npmjs.com/package/#solana/solidity
how can I interact with interfaces through hardhat.
For example in brownie you can just call function from an interface like this:
def main():
weth = interface.IWeth("weth_address")
tx = weth.deposit({"from": account, "value": "value"})
and that's it.
Is there a way to do the same in hardhat? I've been siting on this problem for couple of hours and for the life of me I can't figure out how to do this.
If it's not possible how do I get weth through solidity.
Yes, you can do it with ethers.getContractAt.
import { ethers } from "hardhat";
...
// Assume `ISetup` is an interface of the contract.
const setup = await ethers.getContractAt("ISetup", contractAddress);
In hardhat, you can achieve it using the attachment.
Go to hardhat console: npx hardhat console
Get the contract factory: factory = await ethers.getContractFactory('YourContractName')
Attach to address weth = await factory.attach('weth_address')
Do your function call e.g:
signer = await ethers.getSigner();
await signer.sendTransaction({ to: tokenAddress, value: ethers.utils.parseEther("5.0") });
Hi im new to smart contract. Im trying to code a simple transfer using etherjs and nextjs. Basically below are my code
import {ethers} from 'ethers';
const ContractAddr = '0xB8c77482e45F1F44dE1745F52C74426C631bDD52'; /* BNB Contract address */
const ContractABI =[{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"type":"function"}]
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
let numberOfTokens = ethers.utils.parseUnits('0.2', 18)
const Contract = new ethers.Contract(ContractAddr,ContractABI,signer)
const receiver = '0x8CA65A3Ce90d31a88FAa747c695183C2aefe537f';
Contract.transfer(receiver, numberOfTokens).then((transferResult) => {
console.log(transferResult)
alert("sent token")
}).catch((error) => {
console.error('error',error);
});
on my metamask, it pops up as i wanted as follow :
however when i check the transaction details at the BSCscan Testnet, its showing 0 Value an the receiver is the Contract Address instead of the receiver.
https://testnet.bscscan.com/tx/0x3278d9668391eee98aadf83e8ae58a0b999f2e9c3e5f47a21f504e1c04b24814
Help. Been stuck for a week searching high and low for similiar issue at Stackoverflow :(
You're mixing together two different approaches - sending ERC-20 tokens and sending native currency of the network.
On the Ethereum networks, BNB is an ERC-20 token (link - mind the 0xB8c7... address that you're using in your code).
However, on the BSC networks, BNB is the native currency. So you transfer it using native transactions - the same way as you would transfer ETH on Ethereum.
Assuming your code uses BSC provider:
const provider = new ethers.providers.Web3Provider(window.ethereum);
const params = [{
from: senderAddress,
to: '0x8CA65A3Ce90d31a88FAa747c695183C2aefe537f',
value: ethers.utils.parseUnits('0.2', 18),
}];
const transactionResult = await provider.send('eth_sendTransaction', params);
I want to deploy my contract which contain a constructor (2 account address and a value P), in Remix, I put manually the address of both account and P value, but in truffle, I edited manually the 2_deploy_contracts.js file as follow:
Contract:
constructor(address payable _account1, address payable _account2, uint _P) public {account1 = _account1;account2 = _account2; P = _P;}
2_deploy_contracts.js:
var contract = artifacts.require("contract");
module.exports = function(deployer) {
deployer.deploy(contract, account1, account2, P);};
Thanks in advance for help.
You have to declare and initialize these parameters :
var account1='0x...';
var account2='0x...';
var P=...;
deployer.deploy(contract, account1, account2, P);
so i was facing the similar problem. And there are few things to be noted.
In your contract, you should declare the contracts, constructer something like this:
Here Coin and Reward are my contracts.
constructor(Coin _coinContractsAddress, Reward _rewardContractAddress){
coin_ = _coinContractsAddress;
reward_ = _rewardContractAddress;
}
Now this was for the contract.
Changes in Deployment file should be made like this:
deploy-contracts.js
module.exports = async function() {
await deployer.deploy(Coin);
const coin_ = await Coin.deployed();
await deployer.deploy(Reward);
const reward_ = await Reward.deployed();
//Now we are going to deploy these contracts, address in the 3rd Contract address named Bank.
await deployer.deploy(Bank, coin_.address, reward_.address);
//Point to note is we are deploying the Bank contract and in its constructor at same time we are passing the coin_.address which is the deployed contract address and reward_.address.
}
Now run truffle migrations and it will be successfully deployed. truffle migrate --reset