I am stuck trying to compile a contract using Remix. I am initializing an array as follows:
address[] public wmaticToUsdcPath =[0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270, 0x2791bca1f2de4661ed88a30c99a7a9449aa84174];
But Remix won't compile and is complaining that 0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270 is not an error. The exact error is, this looks like an array but has an invalid checksum. It is suggesting I prepend '00' to it and directing me to https://docs.soliditylang.org/en/develop/types.html#address-literals but I can't seem to understand what to do. Prepending '00' will change the address. I am working on the MATIC/Polygon network.
The funny thing is if I declare an address variable and assign the WMATIC address to it, it is accepted by the compiler.
Does anyone know why the MATIC address is not accepted in an array.
It turns out I just need to follow the instruction in the error message. I prefix the address with '00' and it solved the issue. The issue was caused because WMATIC (and also USDC) have address format that will not pass checksum for later versions of solidity. By adding the '00' it will make it pass the checksum during compilation but the address will still be the same on deploying (I was worried adding this will change the address of the token). My final solution looked like this:
address[] public wmaticToUsdcPath =[address(0x000d500b1d8e8ef31e21c99d1db9a6444d3adf1270), address(0x002791bca1f2de4661ed88a30c99a7a9449aa84174)];
You need to checksum the addresses.
Checksum of an address is basically adjusting capitalization of the letters (hex values a-f) based on values of the address hash. There are some tools to calculate the address checksum, for example this one. You can see the second half of this answer for more detailed explanation.
pragma solidity ^0.8;
contract MyContract {
address[] public wmaticToUsdcPath = [
0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270, // instead of 0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270
0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 // mind the capitalization of the letters
];
}
Related
Hey guys so I was fiddling around with an dapp Idea.
When I get a specific address from the smart contract,
it gives me a specific encoded type
for example 9HUG4x4wVzHmXRedwA6b9ygZbN/KGeDfmRDLgGZtLmI= .
How can I decode that to the the public address I want?
The answer https://stackoverflow.com/a/73395946/2945326 is a way to decode a base64 address into a 32-byte raw address/public key inside a smart contract.
In most cases, you should avoid decoding base64 within a smart contract. Instead, you should ensure that smart contracts always deal directly with raw bytes.
If you want to decode an address outside of a smart contract (for example to display it on a website), then you need to first decode the base64. This gives you a 32-byte raw address/public key.
To be displayed, this needs to be converted to an address following https://developer.algorand.org/docs/get-details/encoding/#address.
Concretely, in Python:
import base64
import algosdk
raw_address_bytes = base64.b64decode("ZXUc/psAtm6K6AOMpvytibbSa8H6WFc6O8XTp/rHuEE=")
address = algosdk.encoding.encode_address(raw_address_bytes)
print(address)
which displays
MV2RZ7U3AC3G5CXIAOGKN7FNRG3NE26B7JMFOOR3YXJ2P6WHXBA4IGKRJ4
See https://forum.algorand.org/t/how-to-convert-public-key-back-to-address-in-js-sdk/3643/3?u=fabrice
you can simple pass that encoded string to pyteal.Base64Decode()
this class would return an string that would be decoded public address.
I'm new to ERC721 and have some question on it.
I was following some tutorial and have question on constructor.
The question parts are below.
constructor(string memory baseURI) ERC721("NFT Collectible", "NFTC") {
setBaseURI(baseURI);
}
I understood what is memory but still don't know what is symbol and name in there.
Can I change it randomly?
What is the purpose of those?
And Where can I find that symbol and name?
That's my question.
I'm freshman in blockchain so some terms are unfamiliar.
So it will be great help if someone tells in details.
Yes, you can change it randomly. It does not matter if you have ERC20 or ERC721 token. Both of them need to have a name and a symbol. Let's say we have us dollar. So the name is "United States dollar" and symbol is "USD".
It is same for your tokens, you need to give them some name and symbol according to the ERC721 technical standard.
#dev Initializes the contract by setting a name and a symbol to the token collection.
// Token name
string private _name;
// Token symbol
string private _symbol;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
you can give your own token name and symbol
for more info you can read this openzeppelin doc
I do not know the purpose of name and symbol but I think that the purpose of ERC721 is to not effect on our nft that we posted on any nft platform example like opensea, Rarible etc. if some how nft marketplaces are hacked then it not be effected.
Hi I am new to solidity and I am wondering why we use the keyword memory when declaring a function, what happens if we choose not to use it? For example
function createObject(string _name, uint _dna) public {
object.push(Object(_name, _dna));
}
instead of
function createObject(string memory _name, uint _dna) public {
object.push(Object(_name, _dna));
if you don't write it, easily it will give error
Without the memory keyword, Solidity tries to declare variables in storage.
Much like RAM, Memory in Solidity is a temporary place to store data whereas Storage holds data between function calls. The Solidity Smart Contract can use any amount of memory during the execution but once the execution stops, the Memory is completely wiped off for the next execution. Whereas Storage on the other hand is persistent, each execution of the Smart contract has access to the data previously stored on the storage area.
That is, the structure of storage is set in stone at the time of contract creation based on your contract-level variable declarations and cannot be changed by future method calls. BUT -- the contents of that storage can be changed with sendTransaction calls. Such calls change “state” which is why contract-level variables are called “state variables”. So a variable uint8 storagevar; declared at the contract level can be changed to any valid value of uint8 (0-255) but that “slot” for a value of type uint8 will always be there.
If you declare variables in functions without the memory keyword, then solidity will try to use the storage structure, which currently compiles, but can produce unexpected results. memory tells solidity to create a chunk of space for the variable at method runtime, guaranteeing its size and structure for future use in that method.
memory cannot be used at the contract level. Only in methods.
The memory keyword tells Solidity to store the parameter in a certain place which allows you to change that parameter inside the function itself. Pretty much like RAM.
Calldata is the same but the parameter is immutable. It's better to use that if you don't plan on changing the parameter inside the function because it's more efficient.
Storage tells Solidity that the value is in the state of the smart contract. It's also more efficient than memory if the parameter is indeed in the state.
You can get more information about the difference between these 3 keywords in this article
Is there any API key / solidity function that would allow me to retrieve real time quotes from exchanges?
I already tried 0x API and DEX.AG but both are quite slow (1/2 calls per sec).
Yes, it is not hard but you will have to put in some work. Lets say you have 1 ETH and you want to know how much DAI the exchange will give you for it.
Example:Uniswap v2 Router:
https://etherscan.io/address/0xf164fc0ec4e93095b804a4795bbe1e041497b92a
Under 'Contracts' you can see the function getAmountsOut (Copied here to make it easier to understand)
function getAmountsOut(uint amountIn, address[] memory path) public view override returns (uint[] memory amounts) {
return UniswapV2Library.getAmountsOut(factory, amountIn, path);
}
This 'getAmountsOut' function will accept an integer amountIn, and two addresses called path.
If we input 1 for amountIn, and two addresses
WETH, DAI
[0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2, 0x6b175474e89094c44da98b954eedeac495271d0f]
the function will return the 'amounts' which is what we asked for which as of the time of writing this is 1695 DAI for 1 WETH.
Here are a couple of tutorials THAT I DID NOT WRITE that should help you get started.
UNISWAP v2: https://soliditydeveloper.com/uniswap2
MORE UNISWAP V2: https://vomtom.at/how-to-use-uniswap-v2-as-a-developer/
For automated market-makers like Uniswap, you can directly use their SDK.
I'm asking this, because I'm not sure if it's a bug or a normal behaviour. Here's a simple contract.
pragma solidity ^0.4.0;
contract Contract {
address public someAddress;
function storeAddress(address someAddress_){
someAddress = someAddress_;
}
}
Store vs Get:
0x203D17B4a1725E001426b7Ab3193E6657b0dBcc6
0x203d17b4a1725e001426b7ab3193e6657b0dbcc6
If EVM understands only lowercased addresses then why do some services generate addresses that are mix-cased?
Capitalization simply means the address has a checksum.Both will work well.
Refer to Is Ethereum wallet address case sensitive? and How can I check if an Ethereum address is valid? for details.