Sign a transaction to smart contract from migrations - blockchain

I want to call smart contract method via sendTransaction from one of migrations. I'm using Truffle. During this migration I create a new wallet with a mnemonic.
const seed = bip39.mnemonicToSeed(mnemonic)
const hdk = hdkey.fromMasterSeed(seed)
const addrNode = hdk.derivePath("m/44'/60'/0'/0/0")
const walletAddr = wallet.getAddressString()
await someFactory.createProfile.sendTransaction(detailsHash, { from: walletAddr })
During the transaction I receive an exception
Returned error: sender account not recognized
How to send transaction with a newly created from a mnemonic profile?

You can set your provider to your contract instance then
const HDWalletProvider = require("#truffle/hdwallet-provider");
const mnemonic = "Your mnemonic"; //
module.exports = function(deployer) {
deployer.deploy(SomeFactory).then(someFactory => {
provider = new HDWalletProvider(mnemonic, "YourURL", 0);
someFactory.contract.setProvider(provider);
someFactory.createProfile.sendTransaction(detailsHash, { from:provider.addresses[0] })
});
};

Related

How can I create a associated token address in solana from connected wallet address?

I want to create an associated token address in Solana from a connected wallet address. This is my code currently:
import { useWallet, useConnection } from "#solana/wallet-adapter-react";
...
const wallet = useWallet();
const { publicKey, sendTransaction } = wallet;
const associatedAccount = await getAssociatedTokenAddress(
mintPubkey,
wallet.publicKey
);
const transaction = new Transaction().add(
createAssociatedTokenAccountInstruction(
wallet.publicKey,
associatedAccount,
wallet.publicKey,
mintPubkey,
TOKEN_2022_PROGRAM_ID,
ASSOCIATED_TOKEN_PROGRAM_ID
)
);
signature = await sendTransaction(transaction, connection, {
skipPreflight: true,
});
await connection.confirmTransaction(signature, "confirmed");
...
But the tx is keep failing like this:
https://solscan.io/tx/ZaQtfVkNkkAweGug2JfDYz8hcFXh4jDUEJoz2Lik6jPv8huFgzpMXMwui51VJsk8yHmpcWUD6UgnqdmRhu4Covh?cluster=devnet
How can I achieve this?
Because you use Token-2022, you need to specify it when generating the associatedAccount address. Otherwise it uses the default Token Program.
Documentation: getAssociatedTokenAddress()
const associatedAccount = await getAssociatedTokenAddress(
mintPubkey,
wallet.publicKey,
false,
TOKEN_2022_PROGRAM_ID,
);

Ethers: invalid object key

I'm tryin send transaction via ethers, seems looks good, but has error...
Connections with wallet ok.
Code bellow:
const { ethers } = require("ethers");
(async () => {
prov2="provider url Alchemy"
const provider = new ethers.providers.JsonRpcProvider(prov2);
let wallet = ethers.Wallet.fromMnemonic("my mnemonic")
const signer = wallet.connect(provider)
const gasPrice = provider.getGasPrice();
let nonce = await provider.getTransactionCount(
wallet.address,
"latest"
);
const recepient = "0x00000000006c3856cbEf3e08E8dF289169EdE581";
let txn = {
type: 2,
chainId: 5,
from: wallet.address,
to: recepient,
value: ethers.utils.parseUnits("0.000001", "ether"),
maxPriorityFeePerGas: ethers.utils.parseUnits("150","gwei"),
maxFeePerGas: ethers.utils.parseUnits("170","gwei"),
nonce: nonce
};
try {
let signedTx = await signer.sendTransaction(txn)
const receipt = await txn.wait();
console.log(receipt);
} catch (e) {
console.log(e.name)
console.log(e.message)
}
})();
And got: invalid object key error ....
I tried googling the error, but got nothing
What can it be?
The error message says "object key error". I suspect that your transaction object.
let txn = {type: 2,...}
is not correct. I checked the https://docs.ethers.io/v5/api/utils/transactions/ and there is no type key property in the transaction object

Owner of smart contract on hardhat development network is being returned 0x00000

I was trying to deploy my smart contract through unit testing using hardhat. The owner upon deployment is being returned as 0x0000.. although when writing my js script i assign a certain address from the hardhat network as the owner.
const hre = require('hardhat')
const { expect, assert } = require('chai')
describe('ProperSubsetFund', async function () {
// Initialize Contract Var
let deployERC20, deployer, user1, user2, trader1, trader2
let signers
beforeEach(async function () {
// Getting all the signers
signers = await hre.ethers.getSigners()
// console.log(signers.map(item => item.address));
// Assign addresses to roles for later use
deployer = signers[0].address
user1 = signers[1].address
user2 = signers[2].address
trader1 = signers[3].address
trader2 = signers[4].address
// Read Contract ERC20
const contractERC20 = await hre.ethers.getContractFactory('ProperSubsetERC20')
// Read Contract Launchpad
const contractLaunchpad = await hre.ethers.getContractFactory('ProperSubsetFactory')
// Read Contract Funds
const contractFunds = await hre.ethers.getContractFactory('ProperSubsetFund')
// Deploy the three contracts
deployERC20 = await contractERC20.connect(signers[0]).deploy(true)
});
describe('Deployment and Ownership', function () {
it('Check if the owner is the deployer', async function () {
expect(await deployERC20.owner()).to.equal(deployer)
});
});
})
These are the results
ProperSubsetFund
Deployment and Ownership
Deployment
Should set the right owner:
AssertionError: expected '0x00000000000000000000000000000000000…' to equal '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb…'
+ expected - actual
-0x0000000000000000000000000000000000000000
+0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
at Context.<anonymous> (test/ProperSubsetFund.test.js:71:49)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
Hardhat is not returning address(0), your contract owner() is returning address(0). If you read the terminal it says
AssertionError: expected '0x00000000000000000000000000000000000…' to equal '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb…'
since you set this:
expect(await deployERC20.owner()).to.equal(deployer)
your deployer address by hardhat is '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb…'. But deployERC20.owner() is '0x00000000000000000000000000000000000…'

SyntaxError: Unexpected token o in JSON at position 1. In Solidity version ^0.8.7

Hey Guys, I'm using latest solidity version 0.8.7. I'm getting this SyntaxError: Unexpected token o in JSON at position 1. Please help me regarding this problem. When I run npm run test command, it gives me this error. I really need help to get rid of this issue. That's why I'm not able to proceed further in learning solidity. Thanks a lot
**Lottery.sol File - **
pragma solidity ^0.8.7; // latest solidity version...
contract Lottery
{
address public manager;
address[] public players;
constructor()
{
manager = msg.sender;
}
function enter() public payable
{
require(msg.value > .01 ether);
players.push(msg.sender);
}
function random() private view returns (uint256)
{
return
uint256(keccak256(abi.encodePacked(block.difficulty, block.timestamp, players)));
}
function pickWinner() public restricted
{
require(msg.sender == manager);
uint256 index = random() % players.length;
uint256 amount = address(this).balance;
payable(players[index]).transfer(amount);
players = new address[](0);
}
modifier restricted()
{
require(msg.sender == manager);
_;
}
function getPlayers() public view returns (address[] memory)
{
return players;
}
}
Compile.js File -
const path = require("path");
const fs = require("fs");
const solc = require("solc");
const lotteryPath = path.resolve(__dirname, 'contracts', 'Lottery.sol');
const source = fs.readFileSync(lotteryPath, "utf8");
var input = {
language: 'Solidity',
sources: {
'lottery.sol' : {
content: source
}
},
settings: {
outputSelection: {
'*': {
'*': [ '*' ]
}
}
}
};
const output = JSON.parse(solc.compile(JSON.stringify(input))); // error on this line probably
const interface = output.contracts['lottery.sol'].lotteryPath.abi;
const bytecode = output.contracts['lottery.sol'].lotteryPath.evm.bytecode.object;
module.exports = {
interface,
bytecode,
};
lottery.test.js File
const assert = require("assert");
const ganache = require("ganache-cli");
const Web3 = require("web3");
const web3 = new Web3(ganache.provider());
const { interface, bytecode } = require("../compile");
let lottery;
let accounts;
beforeEach(async () => {
accounts = await web3.eth.getAccounts();
lottery = await new web3.eth.Contract(JSON.parse(interface)) // error on this line probably
.deploy({ data: bytecode })
.send({ from: accounts[0], gas: '1000000' });
});
describe("Lottery Contract", () => {
it("deploys a contract", () => {
assert.ok(lottery.options.address);
});
});
deploy.js File -
const HDWalletProvider = require("#truffle/hdwallet-provider");
const Web3 = require("web3");
const { interface, bytecode } = require("./compile");
const provider = new HDWalletProvider(
"*******************************************",
"https://rinkeby.infura.io/v3/********************"
);
const web3 = new Web3(provider);
const deploy = async () => {
const accounts = await web3.eth.getAccounts();
console.log("Attempting to deploy from accoutns", accounts[0]);
const result = await new web3.eth.Contract(JSON.parse(interface))
.deploy({ data: bytecode})
.send({ gas: '1000000', from: accounts[0] });
console.log("Contract deployed to", result.options.address);
};
Follow these steps.
Step 1: Check the solidity compiler version
Go to your package.json file. Under the dependencies object you will find the solc version.
Here make sure the solidity version is the same that you used in your Lottery.sol file.
If the version is not the same then please install the right version using npm
In my case, I am using ^0.8.8 in my solidity file. So I run the following command:
npm install solc#0.8.8
Step 2: Update your lottery.test.js file
In your lottery.test.js file update this line
lottery = await new web3.eth.Contract(JSON.parse(interface))
to this
lottery = await new web3.eth.Contract(interface)
Step 3: Update your deploy.js file
In your deploy.js file update this line
const result = await new web3.eth.Contract(JSON.parse(interface))
to this
const result = await new web3.eth.Contract(interface)
Also, it's a good practice to add your deployment code into a try/catch block like this:
try {
const accounts = await web3.eth.getAccounts();
console.log("Attempting to deploy from accoutns", accounts[0]);
const result = await new web3.eth.Contract(interface)
.deploy({ data: bytecode})
.send({ gas: '1000000', from: accounts[0] });
console.log("Contract deployed to", result.options.address);
} catch(error) {
console.log(error);
}
Note: Finally ensure in your deployment account you have enough ethers to test with. If you don't then get some ethers using faucets

Call constructor and deploy with web3 and ropsten

I have created a test contract which has been compiled successfully and want to broadcast on ropsten test network using web3js. I have a metmask account which i am using. I would like to know how can i call constructor of my contract and then broadcast on ropsten.
I did broadcast one of my contract without constructor and do have my transaction hash key which is 0xf7e5a8e93db9989b033b85323cdff713ba88b547ef64a544550e145961999aac but i am getting a following error Error encountered during contract execution [Reverted] and Transaction has been reverted by the EVM on console. I would like to know also why i am getting this error after broadcast has been done
const fs = require('fs')
var Tx = require('ethereumjs-tx').Transaction
const Web3 = require('web3')
const web3 = new Web3('https://ropsten.infura.io/v3/KEY')
deploy()
function deploy () {
const privateKey = 'PRIVATE_KEY'
const account1 = 'ACCOUNT_NUMBER'
const privateKey1 = Buffer.from(privateKey, 'hex')
const contractData = fs.readFileSync('../../build/contracts/Testcontract.json')
const contract = JSON.parse(contractData)
const byteCode = contract['bytecode']
web3.eth.getTransactionCount(account1, (err, txCount) => {
const txObject = {
nonce: web3.utils.toHex(txCount),
gasLimit: web3.utils.toHex(100000),
gasPrice: web3.utils.toHex(web3.utils.toWei('0.004', 'gwei')),
data: byteCode
}
let tx = new Tx(txObject, {'chain':'ropsten'})
tx.sign(privateKey1)
const serializedTx = tx.serialize()
const raw = '0x' + serializedTx.toString('hex')
web3.eth.sendSignedTransaction(raw, (err, txHash) => {
console.log('err: ', err, 'txHash: ', txHash)
})
})
}
My contract with constructor looks like this
pragma solidity ^0.5.11;
contract Testcontract {
string public senderName;
string public receiverName;
uint public transferAmount;
constructor (string memory _sender, string memory _receiver, uint _amount) public {
senderName = _sender;
receiverName = _receiver;
transferAmount = _amount;
}
}
UPDATE
A simple way to deploy a contract through an Infura node is using Truffle. In your project's root directory
$ npm install truffle
$ truffle init
Here is a tutorial on how to configure Truffle to use your Infura project. In short, install Truffle's hd-wallet-provider
$ npm install #truffle/hdwallet-provider
Replace truffle-config.js with
const HDWalletProvider = require("#truffle/hdwallet-provider");
const mnemonic = "orange apple banana...";
module.exports = {
networks: {
ropsten: {
provider: () => new HDWalletProvider(mnemonic, 'https://ropsten.infura.io/v3/<YOUR INFURA PROJECT ID>'),
network_id: 3, // Ropsten's id
},
},
compilers: {
solc: {
version: "0.5.11", // Fetch exact version from solc-bin (default: truffle's version)
}
}
}
The previous code configures Truffle to connect to Infura an use your account. In ./migrations directory (created by truffle init) create a new file 2_deploy_testContrac.js where you can define how to deploy your contract and provide the arguments needed by TestContract.
var TestContract = artifacts.require("./TestContract");
module.exports = function(deployer) {
deployer.deploy(TestContract, "AliceSender", "BobSender", 120);
}
Finally, deploy your contract by executing
$ truffle migrate --network ropsten
The reason why your transaction has been reverted is because the constructor of TestContract expected three arguments but you have given zero. Since the constructor couldn't be executed, your deploying transaction was reverted as well.
Instead of manually creating your deploying transaction, you can use web3.eth.Contract.deploy. With this method you can conveniently provide all parameters required by the contract's constructor.
UPDATE: The solution below won't work with Infura because the Infura API does not expose web3.eth.personal functions and it only allows sending rawTranscations.
You should be able to deploy your contract with the following code. Note that it was mainly copy-pasted from the official web3 documentation.
var contractData = fs.readFileSync('../../build/contracts/Testcontract.json');
var contract = JSON.parse(contractData);
var abi = contract['abi'];
var bytecode = contract['bytecode'];
var testContract = eth3.eth.Contract(abi);
var account = ...;
var password = ...;
web3.eth.personal.unlockAccount(account, password);
testContract.deploy({
data: bytecode,
arguments: ['SenderAlice', 'ReceiverBob', 120]
})
.send({
from: account,
gas: 1500000,
gasPrice: '30000000000000'
}, function(error, transactionHash){
console.log(error, transactionHash);
})
.on('error', function(error){
console.log(error);
})
.on('transactionHash', function(transactionHash){
console.log(transactionHash);
})
.on('receipt', function(receipt){
console.log(receipt.contractAddress) // contains the new contract address
})
.on('confirmation', function(confirmationNumber, receipt){
console.log(confirmationNumber, transactionHash);
})
.then(function(newContractInstance){
console.log(newContractInstance.options.address) // instance with the new contract address
});