While running the deploy_lottery.py I am getting the following error:
The transactions executes until def start_lottery(). Once it reaches the def enter_lottery the programs stops execution with the following error:
1."sender doesn't have enough funds to send tx."
I am running the script in local development chain with a "id" account.
Can you share your code please? mine looks like this and it works
python
def startLotter():
account = get_account()
lottery = Lottery[-1]
starting_tx = lottery.startLottery({"from": account})
starting_tx.wait(1)
print("The lottery has started!!")
solidity
function startLottery() public onlyOwner
{
require(lottery_state == LOTTERY_STATE.CLOSED, "lottery already open");
lottery_state = LOTTERY_STATE.OPEN;
}
the function only has to change the state of the lottery but that does require a transaction so you should have the funds.
Related
Is there a way to retrieve the most recent added/deployed smart contracts to the ethereum chain?
Thanks a lot for any advice.
Regards,
JR
Newly deployed contract addresses are not directly available through the node RPC API (and its wrappers such as ethersjs and web3js), but you can build a script that
Subscribes to newly published blocks
Loops through transaction receipts on the block
And searches for contractAddress property of the transaction receipt
The contractAddress property returns null if the transaction does not deploy a contract (most transactions) or an address if the transaction deploys a contract.
The above mentioned approach only retrieves contracts that were deployed directly - by sending a transaction with empty to field and data field containing the contract bytecode.
It does not retrieve contracts that were deployed using an internal transaction. For example it would not catch the following Hello contract deployment (that is deployed by executing the deployHello() function).
pragma solidity ^0.8;
contract Hello {}
contract HelloFactory {
event Deployed(address);
function deployHello() external {
// deploys a new instance of the `Hello` contract to a new address
address deployedTo = address(
new Hello()
);
emit Deployed(deployedTo);
}
}
If you want to retrieve deployments of these contracts as well, then you'd need to debug each newly produced block and search for the create and create2 opcodes (each of them deploys a new contract, they take different input arguments).
So overall, it's not a simple task but it's doable.
It's generally discouraged to recommend any specific 3rd party APIs and tools here at StackOverflow. But I'm guessing that there are already some existing services that do all of this on their backend, and are able to return the aggregated list of newly deployed contracts as a result.
Thanks to the help of Petr Hejda I created the following Python code:
import sys
import time
from web3 import Web3
def connect():
# infura API key
API_KEY = "INFURA_API_KEY"
# change endpoint to mainnet or ropsten or any other of your account
url = f"https://mainnet.infura.io/v3/{API_KEY}"
w3 = Web3(Web3.HTTPProvider(url))
# res = w3.isConnected()
# print(res)
return w3
def get_latest_block(connection):
return connection.eth.get_block('latest')
def get_latest_block_id(block_information):
return block_information['number']
def search_new_contracts(connection, block_information):
block_transactions = block_information['transactions']
# print(block_transactions)
for transaction in block_transactions:
transaction_data = connection.eth.getTransaction(transaction)
if transaction_data['to'] == "":
print(f"Contract creation transaction: {transaction_data}")
print("Block searching done")
if __name__ == "__main__":
current_block_number = sys.maxsize
connection = connect()
while True:
latest_block = get_latest_block(connection)
latest_block_id = get_latest_block_id(latest_block)
if current_block_number is not latest_block_id:
print(f'New block detected: {latest_block_id}')
search_new_contracts(connection, latest_block)
current_block_number = latest_block_id
Problem is that it is slow so I have to see if I can speed things up.
I deployed following contract in remix.ethereum
0x932FC462d97e23E9fe8d5a1F085d9D611B892666
and hooked it up to my UI at
https://tewkenbak.github.io/tewken/ (this is a contract for testing)
Following things happened
1) in remix.ethereum i wasnt able to compile the contract - no errors
2) i was able to deploy the contract to the mainnet
3) the contract doesnt give me any errors when interacting with it at
https://etherscan.io/address/0x932fc462d97e23e9fe8d5a1f085d9d611b892666#writeContract
4) when I try to interact with contract through my UI - above link i get following Error
the same time I get NO error message in the console
UPDATE
I just checked your source code, looks like you gave the wrong method name here and some other places:
if (walletMode === 'metamask') {
contract.buy(masternode, {
value: convertEthToWei(amount)
}, function (e, r) {
console.log(e, r)
})
}
there is no buy function in the contract.
You gave the wrong abi, since there is no function named buy in your smart contract.
I've successfully deployed my contract to Kaleido but I'm having trouble figuring out how to correctly verify it. Here is the source code deploys the contract and I've verified the the address printed by the last print statement appears in my Kaleido blockchain:
from web3 import Web3
from web3.providers import HTTPProvider
from solc import compile_source
# Solidity source code
contract_source_code = '''
pragma solidity ^0.4.0;
contract Greeter {
string public greeting;
function Greeter() {
greeting = 'Hello';
}
function setGreeting(string _greeting) public {
greeting = _greeting;
}
function greet() constant returns (string) {
return greeting;
}
}
'''
compiled_sol = compile_source(contract_source_code) # Compiled source code
contract_interface = compiled_sol[':Greeter']
w3 = Web3(HTTPProvider("https://XXXXX:YYYYY#ZZZZZZZ.kaleido.io"))
contract_ = w3.eth.contract(
abi=contract_interface['abi'],
bytecode=contract_interface['bin'])
# note: when interacting with kaleido, gasPrice MUST be 0 (I think because of the consensus algorithm I chose)
# and it seems it doesn't matter what account this is sent from
construct_txn = contract_.constructor().buildTransaction({
'from': w3.eth.accounts[0],
'gas': 1728712,
'gasPrice': 0})
txn = w3.eth.sendTransaction(construct_txn)
tx_receipt = w3.eth.getTransactionReceipt(txn)
contract_address = tx_receipt['contractAddress']
print(contract_address)
When I try to verify my contract, I'm asked to provide the source code, the contract name, a compiler version and whether optimization was used.
I use the following for the requested source code
pragma solidity ^0.4.0;
contract Greeter {
string public greeting;
function Greeter() {
greeting = 'Hello';
}
function setGreeting(string _greeting) public {
greeting = _greeting;
}
function greet() constant returns (string) {
return greeting;
}
}
I use Greeter as the contract name. solc --version returns Version: 0.4.24+commit.e67f0147.Darwin.appleclang which I found was committed on May 16: https://github.com/ethereum/solidity/search?q=e67f0147&type=Commits.
I've tried all of the following combinations for compiler version + optimization enabled: {0.4.24, 0.4.24-nightly.2018.5.16} x {optimization enabled, optimization disabled} and none of these combinations worked. I get the following error when I try 0.4.24-nightly.2018.5.16 as the compiler and optimization not enabled.:
The compiled result does not match the input creation bytecode located at 0x4c94e89d5ec3125339906109f143673f40868df2.
Compilation failed: ["Warning: This is a pre-release compiler version, please do not use it in production.\n",":6:5: Warning: Defining constructors as functions with the same name as the contract is deprecated. Use \"constructor(...) { ... }\" instead.\n function Greeter() {\n ^ (Relevant source part starts here and spans across multiple lines).\n",":6:5: Warning: No visibility specified. Defaulting to \"public\". \n function Greeter() {\n ^ (Relevant source part starts here and spans across multiple lines).\n",":14:5: Warning: No visibility specified. Defaulting to \"public\". \n function greet() constant returns (string) {\n ^ (Relevant source part starts here and spans across multiple lines).\n"] .
You should not need compiler parameters in order to verify the contract. Only in rare occasions will you need to know them. I currently use 0.4.21 compiler and was able to verify my contract just with the contract Solidity source code.
I might suggest specifying the specific compiler you are using in your contract pragma, instead of ^0.4.0.
I was also using a Geth PoA environment when I attempted to verify, and had to make a few modifications to your code in order to get this to work. Are you using a Quorum environment? Which protocol?
Here is my code taken from the Quickstart example in the README:
import json
import web3
from web3 import Web3, HTTPProvider
from solc import compile_source
from web3.contract import ConciseContract
from web3.middleware import geth_poa_middleware
# Solidity source code
contract_source_code = '''
pragma solidity ^0.4.21;
contract Greeter {
string public greeting;
function Greeter() public {
greeting = 'Hello';
}
function setGreeting(string _greeting) public {
greeting = _greeting;
}
function greet() public returns (string) {
return greeting;
}
}
'''
compiled_sol = compile_source(contract_source_code) # Compiled source code
contract_interface = compiled_sol['<stdin>:Greeter']
# web3.py instance
w3 = Web3(HTTPProvider("https://YYY:ZZZ#XXXXXX.us-east-2.kaleido.io"))
w3.middleware_stack.inject(geth_poa_middleware, layer=0)
# set pre-funded account as sender
w3.eth.defaultAccount = w3.eth.accounts[0]
# Instantiate and deploy contract
Greeter = w3.eth.contract(abi=contract_interface['abi'], bytecode=contract_interface['bin'])
# Submit the transaction that deploys the contract
tx_hash = Greeter.constructor().transact()
# Wait for the transaction to be mined, and get the transaction receipt
tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)
print(tx_receipt.contractAddress)
# Create the contract instance with the newly-deployed address
greeter = w3.eth.contract(
address=tx_receipt.contractAddress,
abi=contract_interface['abi'],
)
# Display the default greeting from the contract
print('Default contract greeting: {}'.format(
greeter.functions.greet().call()
))
print('Setting the greeting to Nihao...')
tx_hash = greeter.functions.setGreeting('Nihao').transact()
# Wait for transaction to be mined...
w3.eth.waitForTransactionReceipt(tx_hash)
# Display the new greeting value
print('Updated contract greeting: {}'.format(
greeter.functions.greet().call()
))
# When issuing a lot of reads, try this more concise reader:
reader = ConciseContract(greeter)
assert reader.greet() == "Nihao"
If you really need to know how to find the compile time arguments, they are typically provided as kwargs to the compile functions. Here's the source line that would do the magic: https://github.com/ethereum/py-solc/blob/c595d84d9f0ef5f5da0a5d79e7d5fcabecfe5f06/solc/main.py#L106
Following smart contract works fine in Remix and Ganache. However doesn't work on private ethereum blockchains like Kaleido or Azure. What am I missing. When I call setA it consumes all gas and then fails.
pragma solidity ^0.4.24;
contract TestA {
uint public someValue;
function setValue(uint a) public returns (bool){
someValue = a;
return true;
}
}
contract TestB {
address public recentA;
function createA() public returns (address) {
recentA = new TestA();
return recentA;
}
function setA() public returns (bool) {
TestA(recentA).setValue(6);
return true;
}
}
I tried your contract in Kaleido, and found even calling eth_estimateGas with very large numbers was resulting in "out of gas".
I changed the setValue cross-contract call to set a gas value, and I was then able to call setA, and estimating the gas for setA showed just 31663.
recentA.setValue.gas(10000)(6);
I suspect this EVM behavior is related to permissioned chains with a gasprice of zero. However, that is speculation as I haven't investigated the internals.
I've also added eth_estimateGas, and support for multiple contracts in a Solidity file, to kaleido-go here in case it's helpful:
https://github.com/kaleido-io/kaleido-go
Another possibility for others encountering "out of gas" calling across contracts - In Geth if a require call fails in a called contract, the error is reported as "out of gas" (rather than "execution reverted", or a detailed reason for the require failing).
You are hitting the limit of gas allowed to be spent per block. Information about gas limit is included into every block, so you can check what's this value is right now in your blockchain. Currently on Ethereum MainNet, GasLimit (per block) is about 8 millions (see here https://etherscan.io/blocks)
To fix this, you can start your blockchain with modified genesis file. Try to increase value of gasLimit parameter in your genesis file, which specifies the maximum amount of gas processed per block. Try "gasLimit": "8000000".
Try to discard the return statement of setValue method in contract TestA.
pragma solidity ^0.4.24;
contract TestA {
uint public someValue;
function setValue(uint a) public {
someValue = a;
}
}
I've got a queue running some callback requests to endpoint of my users.
Here's the code of my queue.
public function handle()
{
//send webrequest here....
//check the response of user backend
if ($res->getStatusCode() != 200 || $res->getBody()->getContents() != "*received*")
throw new Exception('callback url not reachable');
}
public function failed(Exception $exception)
{
//check tries and try again if needed
//check if job failed for 5 times
//if not ->retry again in 5 minutes, increment the times tried
//if yes ->disable API access, send email
Log::info("user email send, callback disabled!");
}
How to let the job fail (my current exception makes the whole job end), when webrequest answer is != "received" and check if the certain job failed 5 times?
If a job failed it should be tried again in 5 minutes.
I don't understand the doc regarding these points.
I know it's too late but yesterday I had the same problem with the queue and when I throw a new exception the queue run it again and again until my VM hanged up. actually, you did right the only thing you have to add to your code is define a tries variable to the public area of your job class and it should run only for example 5 times and pushed to failed job ;)
class NewCustomer implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 5;
.
.
.