Tron Wallet address declaration format in Solidity - solidity

I'm trying to build a simple contract that just forwards any incoming transferred amount to a set wallet address. I managed to get this contract to work using the Remix IDE with ethereum addresses but I cannot port it to Tron now. In the TronIDE I cannot compile the line declaring the wallet address.
Here is the contract code I am using. Can anyone shed some light on what format the tron wallet address needs to be in. I tried converting it to hex (transferTo variable) and it didn't work, I tried using the base58 address and it didn't work.
Aparently it does compile fine in the TronIDE compiler with the ethereum address though, I even managed to deploy it to Shasta without any issues (except for it to forward the actual transferred amounts of course).
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract PaymentForwarder {
address constant transferTo = 414dbc78301522ae1529d01f4093ae3daad3f26827; // this throws a ParseError: Identifier-start is not allowed at end of a number.
address constant transferToAlternative = TH4EovGaTrmWxhJSmeMVKy5ZpnDGE3DgJ8; // this thows a DeclarationError: Undeclared identifier.
address constant workingDeclaration = 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2; // this works fine in the tron solidity compiler even though it's an ethereum address
event TransferReceived(address _from, uint _amount);
constructor() {
}
receive() payable external {
address payable paya = payable(transferTo);
paya.transfer(msg.value);
emit TransferReceived(msg.sender, msg.value);
}
}
Can anyone shed some light on why this is and what format does the wallet address need to be in?
Thank you

If you already have the hexstring like transferTo (from quick glance), then you can simply add the hexstring with 0x in the beginning, and convert it to EVM address with the following function.
/**
* #dev convert uint256 (HexString add 0x at beginning) tron address to solidity address type
* #param tronAddress uint256 tronAddress, begin with 0x, followed by HexString
* #return Solidity address type
*/
function convertFromTronInt(uint256 tronAddress) public view returns(address){
return address(tronAddress);
}
On the other hand, transferToAlternative is still in its original TRON address form, then you'll need to use tronweb TRON's official library and convert the address to its hexstring form with the following function:
tronWeb.address.toHex("TH4EovGaTrmWxhJSmeMVKy5ZpnDGE3DgJ8")
Then simply, continue to the step above to convert it fully to EVM address.
Hope this helps!
Source:
Contract Address Using in Solidity Language: https://developers.tron.network/v4.4.0/docs/contract-address-using-in-solidity-language
Tronweb address Reference: https://developers.tron.network/reference/address
Cheers~

Related

How can I get metadata and my image to show up on OpenSea Testnet?

I followed along with Remix's beginner NFT course and successfully deployed a few NFTs using the Goerli testnet and their provided IPFS data. I uploaded my own image and metadata and can see it on IPFS but neither the metadata nor the image is populating on OpenSea.
Here is the code for the contract I am deploying:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "#openzeppelin/contracts#4.4.0/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts#4.4.0/access/Ownable.sol";
contract Donation is ERC721, Ownable {
constructor() ERC721("Donation", "DONO") {}
function _baseURI() internal pure override returns (string memory) {
return "https://ipfs.io/ipfs/QmXZKcU9WDZxvXvxoAL4YdZVR5Ssj97ayEYRPqYBHrRSb2";
}
function safeMint(address to, uint256 tokenId) public onlyOwner {
_safeMint(to, tokenId);
}
}
Please see the URL that I return for my metadata and subsequent link to my image. Is there anything you see that is immediately wrong that would indicate why nothing is populating (in the JSON file, code, or otherwise)?
For ERC721, the _baseURI will essentially be the base to be combined with the NFT's token id, so for example NFT with token ID 0 will have the tokenURI of:
https://ipfs.io/ipfs/QmXZKcU9WDZxvXvxoAL4YdZVR5Ssj97ayEYRPqYBHrRSb2/0
which in this case after checking is invalid as https://ipfs.io/ipfs/QmXZKcU9WDZxvXvxoAL4YdZVR5Ssj97ayEYRPqYBHrRSb2 should be the valid tokenURI itself. OpenZeppelin designed the ERC721 contract this way as it is the most gas-efficient way to create a standard ERC721 NFT. However, the drawback is that it made it difficult to provide modified URI for each token ID.
If you like to set tokenURI with different base for different token ID, then you should instead check ERC721URIStorage in the contract wizard. This way, the ERC721 NFT contract will have the _setTokenURI(tokenId, uri) function, which allows you to modify the tokenURI for different token ID. However, keep in mind that this will be very expensive on the user side as string inputs cost a lot in EVMs.
Hope this helps~

Created custom ERC20 contract, balanceOf msg.sender is zero

I've created a ERC20 contract in Remix:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {
constructor(string memory name, string memory symbol) ERC20(name, symbol) {
_mint(msg.sender, 1002000);
}
}
Then I deployed it:
But the balance of msg.sender is zero:
Does anyone know what's wrong?
I just tried your code and it works perfectly like intended.
It is important, that you compile the correct contract using Remix, see my attached picture. You need to choose the contract "MyToken". I guess you could have deployed the contract "ERC20 - #openzeppelin/contracts/token/ERC20/ERC20.sol" which would lead to the behaviour you mentioned.
compile "MyToken" in Remix

How is uniswap assembly create2 function working?

I was going through uniswap code trying to understand the code and most of it is pretty clear but I do have a few questions.
in this function:
function createPair(address tokenA, address tokenB) external returns (address pair) {
require(tokenA != tokenB, 'UniswapV2: IDENTICAL_ADDRESSES');
(address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
require(token0 != address(0), 'UniswapV2: ZERO_ADDRESS');
require(getPair[token0][token1] == address(0), 'UniswapV2: PAIR_EXISTS'); // single check is sufficient
bytes memory bytecode = type(UniswapV2Pair).creationCode;
bytes32 salt = keccak256(abi.encodePacked(token0, token1));
assembly {
pair := create2(0, add(bytecode, 32), mload(bytecode), salt)
}
IUniswapV2Pair(pair).initialize(token0, token1);
getPair[token0][token1] = pair;
getPair[token1][token0] = pair; // populate mapping in the reverse direction
allPairs.push(pair);
emit PairCreated(token0, token1, pair, allPairs.length);
There is the assembly line. According to solidity docs this deploys a new contract but I don't understand how it works where it gets the code from and so on.
So is it possible to "translate" this into solidity somehow? Thanks a lot!
It makes use of the create2 opcode allowing you to deploy a contract to an address determinable by its bytecode and salt.
Uniswap V2 was written in Solidity 0.5 that didn't have a way to produce the create2 opcode directly from the language. So you had to use a low-lewel assemly to actually use this opcode.
The current version 0.8 allows passing the salt param producing the create2 (instead of the regular create) opcode.
pragma solidity ^0.8;
contract UniswapV2Pair {
}
contract MyContract {
function createPair() external {
bytes32 salt = 0x1234567890123456789012345678901234567890123456789012345678901234;
address pair = address(
new UniswapV2Pair{salt: salt}()
);
}
}
Uniswap uses a combination of the pair token addresses as the salt, and the bytecode is always the same. Which effectively allows to deploy just one contract for each unique pair combination.
Example:
Tokens 0x123 and 0x456 would always result in UniswapV2Pair contract address 0xabc.
But once you change the salt, it changes the deployed contract address. So tokens 0x123 and 0x789 would always result in UniswapV2Pair contract address 0xdef.

safeTransfer with token erc1155 in solidity 0.8

I get this error
ERC1155: transfer to non ERC1155Receiver implementer when try to transfer to a smart contract I found this doc https://docs.openzeppelin.com/contracts/4.x/api/token/erc1155 but still don't know how to fix this do I have to abstract IERC1155Receiver interface in my holder token 1155
The receiving contract needs to implement the onERC1155BatchReceived() function based on the ERC-721 definition.
pragma solidity ^0.8;
contract MyContract {
function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes memory _data) external returns(bytes4) {
// here you can (but don't have to) define your own logic - emit an event, set a storage value, ...
// this is the required return value described in the EIP-721
return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"));
}
}

Solidity 'out of gas' exception when trying to transfer Ether

I try to transfer Ether from the contract to an address but it gives the error that the transaction is out of gas. I think it's a small problem but I can't find it. I have to specifically use solidity version 0.4.24.
The warning from Remix
The error from MetaMask
I have tried different methods, like:
address.transfer(amount);
address.send(amount);
address.call.value(amount)( );
All methods will give the same out of gas exception. and the send and call method will also give a warning that it's outdated and that I should use the transfer method.
I also tried to adjust the gas and it didn't work, I also tried the needed 2,300 for the transfer listed on the docs.
The code:
pragma solidity ^0.4.24;
contract TestContract {
function payAddress(address _address) external payable {
_address.transfer(msg.value);
}
}
If the problem is that the contract doesn't have any Ether to transfer, can it use the Ether I send with the function call? Or is the problem something else?
Thank you for reading.
edit:
I have tried to send Ether to my Contract and that works, I do have Ether on my contract now, but the function still gives the same error as before. So the problem is something else.
Current code:
pragma solidity ^0.4.24;
contract TestContract {
function() external payable { }
function payContract() public payable {}
function paySomeone(address _address, uint256 _amount) external {
_address.transfer(_amount);
}
function getBalance() public view returns (uint256) {
return address(this).balance;
}
}
The balance of the contract
The parameters I use
Same MetaMask error as before
As you can see here the balance of the contract is 10 wei, but when i try to send 9 wei it still gives the same out of gas error. I also still get the same error from Remix as before.
I also post the issue on the Stack exchange and got an answer there. The issue was my
Ganache version. I switched to the Robsten test network and it worked. I'll link the post here.
Yes. In order to send ether from contract to another address, first you must send some ether to the contract address. Take a look at this and this.