Getting contract address - ethereum

I saw an example about this, while was searching it on the internet.
I want to deploy a new contract which is ProjectContract. However, I could not get contract address as below. I think this is for old version.
address newProjectAddress = new ProjectContract(name, description, requiredPrice, msg.sender);
And the error message is:
How can I do that for the new versions?

When you're creating new <contractName>, it returns the contract instance. You can cast it to the address type and get the contract address.
pragma solidity ^0.8.4;
contract ProjectContract {
constructor (string memory name, string memory description, uint256 requiredPrice, address owner) {
}
}
contract MyContract {
event LogAddress(address _address);
function createProjectContract(string memory name, string memory description, uint256 requiredPrice) external {
ProjectContract newProjectInstance = new ProjectContract(name, description, requiredPrice, msg.sender);
address newProjectAddress = address(newProjectInstance); // here
emit LogAddress(newProjectAddress);
}
}

Related

"Execution reverted" error when I call createCollectible function on goerli testnet

I'm new to smart contract and Solidity programming and I've been trying to deploy an NFT contract on goerli testnet. The contract deploys without any problem but when I try to call the "createCollectible" function, I get the following error:
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
execution reverted
{
"originalError": {
"code": 3,
"data": "0xf0019fe60000000000000000000000000000000000000000000000000000000000000c6a000000000000000000000000b54644506388a04187d943dbbbd3edbb3ee53094",
"message": "execution reverted"
}
}
Here is my contract:
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.9.0;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
import "#chainlink/contracts/src/v0.8/interfaces/LinkTokenInterface.sol";
import "#chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
/**
* #title The AdvandedCollectible contract
* #notice A contract that mints an NFT
*/
contract AdvancedCollectible is ERC721, VRFConsumerBaseV2 {
VRFCoordinatorV2Interface immutable COORDINATOR;
LinkTokenInterface immutable LINKTOKEN;
uint256 public tokenCounter;
uint64 immutable s_subscriptionId;
// The gas lane to use, which specifies the maximum gas price to bump to.
// For a list of available gas lanes on each network,
// see https://docs.chain.link/docs/vrf-contracts/#configurations
bytes32 immutable s_keyhash;
uint32 immutable s_numWords = 1;
uint16 immutable s_requestConfirmations = 3;
// Depends on the number of requested values that you want sent to the
// fulfillRandomWords() function. Storing each word costs about 20,000 gas,
// so 100,000 is a safe default for this example contract. Test and adjust
// this limit based on the network that you select, the size of the request,
// and the processing of the callback request in the fulfillRandomWords()
// function.
uint32 immutable s_callbackGasLimit = 100000;
uint256 public s_requestId;
uint256 public s_randomWords;
address s_owner;
enum Breed {
PUG,
SHIBA_INU,
ST_BERNARD
}
mapping(uint256 => Breed) public tokenIdToBreed;
mapping(uint256 => address) public requestIdToSender;
event requestCollectible(uint256 indexed requestId, address requester);
event breedAssigned(uint256 tokenId, Breed breed);
constructor(
address vrfCoordinator,
address link,
bytes32 keyhash,
uint64 subscriptionId
) VRFConsumerBaseV2(vrfCoordinator) ERC721("Dogie", "DOG") {
tokenCounter = 0;
COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator);
LINKTOKEN = LinkTokenInterface(link);
s_keyhash = keyhash;
s_owner = msg.sender;
s_subscriptionId = subscriptionId;
}
modifier onlyOwner() {
require(msg.sender == s_owner, "You are not the owner");
_;
}
function createCollectible() public returns (uint256) {
s_requestId = COORDINATOR.requestRandomWords(
s_keyhash,
s_subscriptionId,
s_requestConfirmations,
s_callbackGasLimit,
s_numWords
);
requestIdToSender[s_requestId] = msg.sender;
emit requestCollectible(s_requestId, msg.sender);
}
function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords)
internal
override
{
s_randomWords = randomWords[0];
Breed breed = Breed(s_randomWords % 3);
uint256 newTokenId = tokenCounter;
tokenIdToBreed[newTokenId] = breed;
emit breedAssigned(newTokenId, breed);
address owner = requestIdToSender[requestId];
_safeMint(owner, newTokenId);
tokenCounter++;
}
function setTokenURI(uint256 tokenId, string memory _tokenURI) public {
require(
_isApprovedOrOwner(_msgSender(), tokenId),
"ERC721: Caller is not owner nor approved."
);
setTokenURI(tokenId, _tokenURI);
}
}
Does anybody have an idea what I'm doing wrong here?
So I realized that I'm missing one small yet important step, and that is adding a consumer to my subscription.
Using the Chainlink VRF V2, you need to create a subscription, add funds to that subscription and add the address where your contract is deployed at as a consumer to the subscription. I wasn't doing that last step and that's why my transaction's execution kept reverting.

Solidity 0.5.1, when creating a contract object, why do we have to pass the token to that contract's constructor even if there is no constructor

Here is the code:
pragma solidity 0.5.1;
contract ERC20Token{
string public name;
mapping(address => uint256) public balances;
function mint() public{
balances[tx.origin] += 1;
}
}
contract MyContract {
address payable wallet;
address public token;
constructor(address payable _wallet, address _token) public {
wallet = _wallet;
token = _token;
}
function() external payable {
buyToken();
}
function buyToken() public payable{
ERC20Token _token = ERC20Token(address(token));
_token.mint();
wallet.transfer(msg.value);
}
}
Process:
First, we are getting the ERC20Token contract address by deploying the ERC20Token contract in the first place.
Secondly, MyContract constructor takes (a wallet address and the ERC20Token contract address) as two parameters.
Then, we create a ERC20Token contract object from this line
ERC20Token _token = ERC20Token(address(token));
I got confused by how this line worked. Even the ERC20Token contract does not contain any constructor, where the above code passes the token as a parameter to the ERC20Token constructor.
If i delete the token parameter from the above code:
ERC20Token _token = ERC20Token();
I will get an error called
Exactly one argument expected for explicit type conversion
Could anyone explain to me why this happens in solidity?
Without the new keyword, you're making a pointer to an already deployed instance of the ERC20Token contract, passing its address in the argument. Since the contract is already deployed and the constructor has been already executed, you do not pass its constructor params.
// address of existing instance
ERC20Token _token = ERC20Token(address(token));
With the new keyword, you'd be deploying a new instance of ERC20Token, specifying its constructor params. Its address is then available by typecasting the variable to address type.
// creating new instance
// passing constructor params (in your case empty)
ERC20Token _token = new ERC20Token();
// address of the newly deployed contract
address tokenAddress = address(_token);

ERC721 contract deployed with create2 stops working after a particular function is called

So I'm working on an NFT marketplace smart contract and one of the features in this marketplace allows users to deploy their own collection (this is basically a smart contract that extends the ERC721 specification). For this, I'm leveraging the create2 opcode. It deploys well while testing on the testnet (except for the insanely huge gas requirement) but the problem is, I can only call a function once in this contract. This is the contract that extends ERC721:
pragma solidity ^0.8.0;
import '#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol';
import '#openzeppelin/contracts/token/ERC721/IERC721.sol';
import '#openzeppelin/contracts/security/ReentrancyGuard.sol';
import '#openzeppelin/contracts/utils/Counters.sol';
import './interfaces/IDeployableCollection.sol';
contract DeployableCollection is IDeployableCollection, ERC721URIStorage, ReentrancyGuard {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
address public _collectionOwner;
bytes32 public _category;
address payable public _paymentReceiver;
string public _collectionURI;
mapping(address => uint256) public lastMintedForIDs;
constructor(
string memory name_,
string memory symbol_,
address collectionOwner_,
string memory category_,
address paymentReceiver_,
string memory collectionURI_
) ERC721(name_, symbol_) {
_collectionOwner = collectionOwner_;
_category = keccak256(abi.encode(category_));
_paymentReceiver = payable(paymentReceiver_);
_collectionURI = collectionURI_;
}
function mintFor(string memory _tokenURI, address to) external nonReentrant returns (uint256 _tokenId) {
_tokenIds.increment();
_tokenId = _tokenIds.current();
_mint(to, _tokenId);
_setTokenURI(_tokenId, _tokenURI);
lastMintedForIDs[to] = _tokenId;
}
}
This is the line that deploys the contract:
function deployCollection(
string memory name_,
string memory symbol_,
string memory category_,
address paymentReceiver_,
string memory _collectionURI
) external payable nonReentrant {
uint256 _fee = _utilityToken != address(0) && IERC20(_utilityToken).balanceOf(_msgSender()) >= _requiredHold
? _collectionDeployFeeInEther.sub((uint256(_percentageDiscount).mul(_collectionDeployFeeInEther)).div(100))
: _collectionDeployFeeInEther;
require(msg.value >= _fee, 'FEE_TOO_LOW');
bytes memory _byteCode = abi.encodePacked(
type(DeployableCollection).creationCode,
abi.encode(name_, symbol_, _msgSender(), category_, paymentReceiver_, _collectionURI)
);
bytes32 _salt = keccak256(abi.encode(name_, _msgSender()));
address _collection;
assembly {
_collection := create2(0, add(_byteCode, 32), mload(_byteCode), _salt)
}
emit CollectionDeployed(_collection, _msgSender(), block.timestamp, name_, category_, symbol_);
}
Now this works fine, except once I call mintFor and an NFT gets minted, the contract stops working. It shows a total supply of zero (0) on the block explorer even though an NFT has been created (I'm only able to create an NFT with an ID of 1). I also am not able to call any function again as it raises an exception (the cause of which is unknown). This is the line in the factory contract that does the actual minting:
function mintNFT(
address collection,
string memory tokenURI_,
address _for
) external payable nonReentrant returns (bool) {
uint256 _fee = _utilityToken != address(0) && IERC20(_utilityToken).balanceOf(_msgSender()) >= _requiredHold
? _mintFeeInEther.sub((uint256(_percentageDiscount).mul(_mintFeeInEther)).div(100))
: _mintFeeInEther;
require(msg.value >= _fee, 'FEE_TOO_LOW');
address _paymentReceiver = IDeployableCollection(collection)._paymentReceiver();
uint256 _feeForOwner = (uint256(_percentageForCollectionOwners).mul(_fee)).div(100);
_safeMintFor(collection, tokenURI_, _for);
_safeTransferETH(_paymentReceiver, _feeForOwner);
uint256 _tokenId = IDeployableCollection(collection).lastMintedForIDs(_msgSender());
emit Mint(collection, _tokenId, block.timestamp, tokenURI_, _msgSender());
return true;
}
I'm guessing an optimization with a runs of 1 is applied upon deployment using create2 (forgive me if this is stupid) but I also think it isn't likely as I'm also watching for events on the smart contract with a Nodejs back-end and I'm able to call '_collectionURI()' when the event data is propagated to my back-end app and this is before calling mintFor. I'm confused! Please help!
This is a link to the contract info on the explorer: https://testnet.bscscan.com/token/0x6dd5bd0072cdc5e8c24f262a9631c175bc2356a0

Chainlink job is not being called by the Solidity Smart Contract using Operator.sol contract

The job spec deployed and running on Chainlink node is being successfully triggered and completed when called using the Solidity smart contract that is using the Oracle.sol contract.
But, since the requirement is to return the large response (https://docs.chain.link/docs/large-responses/), so I have to use Operator.sol contract instead of Oracle.sol. Then, the job is not being called.
The deployed Operator contract is looking as:
The LINK Token and Owner addresses that I have used to deploy the Operator.sol contract are:
The LINK Token address is basically taken from the official Chainlink doc (https://docs.chain.link/docs/fulfilling-requests/) mentioning the Kovan Testnet LINK token address:
And the owner address is taken from the Account address of the running Chainlink node:
And the Solidity smart contract code is:
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "#chainlink/contracts/src/v0.8/ChainlinkClient.sol";
contract GenericLargeResponse is ChainlinkClient {
using Chainlink for Chainlink.Request;
bytes public data;
constructor(
) {
setChainlinkToken(0xa36085F69e2889c224210F603D836748e7dC0088);
setChainlinkOracle(0x8114f13FaF377FFc7A5AD32fb8a1e448667b871D);
}
function requestBytes(
)
public
{
bytes32 specId = "a3d1b2c945244e44bdb412c5b5287df3";
uint256 payment = 100000000000000000;
Chainlink.Request memory req = buildChainlinkRequest(specId, address(this), this.fulfillBytes.selector);
req.add("data", "{\"agg_x\": \"agg_mean\", \"dataset_code\":\"MODIS/006/MOD14A1\", \"selected_band\":\"MaxFRP\", \"image_scale\":1000, \"start_date\":\"2021-09-01\", \"end_date\":\"2021-09-10\", \"geometry\":{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"properties\":{\"id\":1},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[29.53125,19.642587534013032],[29.53125,27.059125784374068],[39.90234375,27.059125784374068],[39.90234375,19.642587534013032],[29.53125,19.642587534013032]]]}},{\"type\":\"Feature\",\"properties\":{\"id\":2},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[46.40625,13.752724664396988],[46.40625,20.138470312451155],[56.25,20.138470312451155],[56.25,13.752724664396988],[46.40625,13.752724664396988]]]}}]}}");
sendOperatorRequest(req, payment);
}
function fulfillBytes(
bytes32 requestId,
bytes memory bytesData
)
public
recordChainlinkFulfillment(requestId)
{
data = bytesData;
}
}
The contract is compiled and deployed successfully. But the requestBytes function is unable to trigger the job-spec running on the Chainlink node.
PS: The function of the similar smart contract that is using the Oracle.sol is successfully triggering the job-spec.
The TOML Job spec running on Chainlink node is:
type = "directrequest"
schemaVersion = 1
name = "shamba-fire-data"
contractAddress = "0x8114f13FaF377FFc7A5AD32fb8a1e448667b871D"
maxTaskDuration = "0s"
observationSource = """
decode_log [type="ethabidecodelog"
abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)"
data="$(jobRun.logData)"
topics="$(jobRun.logTopics)"]
decode_cbor [type="cborparse" data="$(decode_log.data)"]
fetch [type="bridge" name="shamba-fire-bridge" requestData="{\\"id\\": $(jobSpec.externalJobID), \\"data\\":$(decode_cbor.data)}"]
parse [type="jsonparse" path="result,1,0" data="$(fetch)"]
encode_data [type="ethabiencode" abi="(uint256 value)" data="{ \\"value\\": $(parse) }"]
encode_tx [type="ethabiencode"
abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)"
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}"
]
submit_tx [type="ethtx" to="0x8114f13FaF377FFc7A5AD32fb8a1e448667b871D" data="$(encode_tx)"]
decode_log -> decode_cbor -> fetch -> parse -> encode_data -> encode_tx -> submit_tx
"""
externalJobID = "a3d1b2c9-4524-4e44-bdb4-12c5b5287df3"
Can anyone please point me in the right direction, like what I'm doing wrong in these steps due to which the smart contract is unable to trigger the job-spec ?
First of all, the owner address of the Operator.sol should be the Metamask wallet Kovan testnet address (instead of the account address of the running Chainlink node) from which the transactions are being done.
Then, after the Operator.sol being deployed successfully, call the setAuthorizedSenders function of the Operator.sol by passing in the account address of the running Chainlink node in the senders address[] field like:
Then, the job-spec's encode_data should be having requestIdparameter as well:
encode_data [type="ethabiencode" abi="(bytes32 requestId, uint256[][] value)" data="{ \\"requestId\\": $(decode_log.requestId), \\"value\\": $(parse) }"]
The entire job-spec should be:
type = "directrequest"
schemaVersion = 1
name = "shamba-fire-data"
contractAddress = "0xf4434feDd55D3d6573627F39fA39867b23f4Bf7F"
maxTaskDuration = "0s"
observationSource = """
decode_log [type="ethabidecodelog"
abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)"
data="$(jobRun.logData)"
topics="$(jobRun.logTopics)"]
decode_cbor [type="cborparse" data="$(decode_log.data)"]
fetch [type="bridge" name="shamba-fire-bridge" requestData="{\\"id\\": $(jobSpec.externalJobID), \\"data\\":$(decode_cbor.data)}"]
parse [type="jsonparse" path="result" data="$(fetch)"]
encode_data [type="ethabiencode" abi="(bytes32 requestId, uint256[][] value)" data="{ \\"requestId\\": $(decode_log.requestId), \\"value\\": $(parse) }"]
encode_tx [type="ethabiencode"
abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)"
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}"
]
submit_tx [type="ethtx" to="0xf4434feDd55D3d6573627F39fA39867b23f4Bf7F" data="$(encode_tx)"]
decode_log -> decode_cbor -> fetch -> parse -> encode_data -> encode_tx -> submit_tx
"""
externalJobID = "66229880-79e1-43c6-9d9e-0eb4b668729d"
Similarly, the solidity smart contract code should be:
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "#chainlink/contracts/src/v0.8/ChainlinkClient.sol";
contract GenericLargeResponse is ChainlinkClient {
using Chainlink for Chainlink.Request;
uint256[][] public data;
constructor(
) {
setChainlinkToken(0xa36085F69e2889c224210F603D836748e7dC0088);
setChainlinkOracle(0xf4434feDd55D3d6573627F39fA39867b23f4Bf7F);
}
function requestBytes(
)
public
{
bytes32 specId = "6622988079e143c69d9e0eb4b668729d";
//0x3065666666656632313564353466316339663332623636376466613061346536;
uint256 payment = 1000000000000000000;
Chainlink.Request memory req = buildChainlinkRequest(specId, address(this), this.fulfillBytes.selector);
req.add("data", "{\"agg_x\": \"agg_mean\", \"dataset_code\":\"MODIS/006/MOD14A1\", \"selected_band\":\"MaxFRP\", \"image_scale\":1000, \"start_date\":\"2021-09-01\", \"end_date\":\"2021-09-10\", \"geometry\":{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"properties\":{\"id\":1},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[29.53125,19.642587534013032],[29.53125,27.059125784374068],[39.90234375,27.059125784374068],[39.90234375,19.642587534013032],[29.53125,19.642587534013032]]]}},{\"type\":\"Feature\",\"properties\":{\"id\":2},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[46.40625,13.752724664396988],[46.40625,20.138470312451155],[56.25,20.138470312451155],[56.25,13.752724664396988],[46.40625,13.752724664396988]]]}}]}}");
sendOperatorRequest(req, payment);
}
function fulfillBytes(
bytes32 requestId,
uint256[][] memory bytesData
)
public
recordChainlinkFulfillment(requestId)
{
data = bytesData;
}
}

Sending Ether failing in smart contract failing

I am learning solidity and testing out accepting payment of a fixed amount using a smart contract.
I took this code from a tutorial website and im testing it in Remix.
pragma solidity ^0.8.7;
contract DonateContract {
address payable public owner;
//contract settings
constructor() {
owner = payable(msg.sender);
}
//public function to make donate
function donate() public payable {
(bool success,) = owner.call{value: 10000 wei}("");
require(success, "Failed to send money");
}
}
I want to transfer a fixed amount of 10000 WEI.
The message sender has a 100 ETH balance.
The owner is just an address, not a contract.
It gives the error "Failed to send money" every time.
The problem here is that by sending a fixed wei amount to the owner, you do not know if the contract will have enough balance to make the transaction. To do so, I would suggest maybe transferring the msg.value amount, so that you ensure that all the eth sent to the contract is redirected to the owner's balance. It would be something like this:
(bool success,) = owner.call{value: msg.value}("");
Hope you find this information useful :)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract transfertot{
//address public address1=0x5B38Da6a701c568545dCfcB03FcB875f56beddC4; it is owner address sample
address public address2=0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db; // it is reciever address sample
address payable public owner;
constructor()payable {
owner=payable(msg.sender);
}
uint public msgvalue=msg.value;//contract value
uint balance1;//owner balance
uint balance2;//reciever balance
uint[] balance1arr;
uint[] balance2arr;
function transfer1(address payable _address,uint _priceGwei)payable public {
require(_priceGwei<=(msgvalue/10**9),"balance is less than msgvalue");//working in gwei
_address.transfer(_priceGwei*10**9);
balance1=owner.balance/(10**9);
balance2=address2.balance/(10**9);
balance1arr.push(balance1);
balance2arr.push(balance2);
msgvalue-=_priceGwei*10**9;
}
function ownerbalancearr()public view returns(uint[] memory){
return balance1arr;
}
function recieverbalancearr()public view returns(uint[] memory){
return balance2arr;
}
}
//when you want to deploy add some gwei to value in deploy and run transactions panel`
//the contract value is differ from owner value
//you can check the`enter code here` output in this code
//good day to you`