solang
solang copied to clipboard
Milestone 11: Write Solidity to Substrate porting guide
This milestone is a documentation effort. This should be a guide which explains how to port existing Solidity contracts to Substrate. This should include:
- How to set up your development environment, including the visual code extension
- How to write a simple contract, how to deploy and use
- How to use this contract from typescript
- How Solidity on Substrate differs from Solidity on Ethereum
- How to port existing solidity code to Substrate
- List of additional features on Substrate
- List of solidity constructs not supported on Substrate and how to translate them for Substrate
- Where to ask for help
The documentation should be formatted in restructuredtext and added to the solang repository.
Success means that a pull request has had all its review comments addressed and it is merged.
in the discord channel, @extraymond gave us already some useful insight about possible topics to consider, especially about How to port existing solidity code to Substrate
:
I think the solang docs are already wonderful and clear on most of the implementation details. But since information are scattered across the doc, with some items have specific towards substrate and some not.
What I think lacking is a refreshing for solidity devs about several conventions, so use cases for most of the essential components needed some counter example to show case that if it's:
- just the same as solidity on eth
- you can but you don't need to, due to solang optimization
- you cannot use the conventional method, but alternative are possible
- it's totally unavailable
I think this can be supported by either a reference example for some of the topics, and by collecting a list of substrate.stackoverflow posts around convention.
For example, my colleague is currently collecting ways to upgrade solang contracts, and one convention won't work due to lacks of delegatecall on substrate. While alternative method works, such as proxy contract or diamond contract, it's also possible to use pallet-contract set-code. A comparison about each of the method for upgradeability should be helpful in this case.
thanks!
I am extremely keen to know the progress made here. Where is best to keep updated on the porting guide for Solidity to Substrate?
Some simple things keep me away from using "Solang + Contracts Pallet on Substrate" when compared with simply using EVM-Compatible Frontier. I am very aware that Solang + Contracts Pallet have much more runtime efficiency benefits however without the guide, it would be extremely difficult:
- Could you share how a team can take a Hardhat-ready project with mutiple sol files and port it for the Solang compilation?
- What should be done if statements like import "@openzeppelin/contracts/token/ERC20/ERC20.sol" are previously used, what is a best-practice to extract out the underlying imports?
Hi @joshuacheong
The best place to keep updated is probably this issue, or also the discord chat where you asked as well. So currently there is no progress made here. You can also refer to the roadmap in our README; this will be something for solang 0.4.
Note that I am aware that the user experience, compared to the tooling of the ETH world, is lacking as of now. However I can only do one thing at the time, so any contributions to improve the situation are highly welcome.
Could you share how a team can take a Hardhat-ready project with multiple sol files and port it for the Solang compilation?
This depends on the specific case. Solang supports compiling multiple .sol files. If you run into issues, feel free to ask in our discord channel.
What should be done if statements like import "@openzeppelin/contracts/token/ERC20/ERC20.sol" are previously used, what is a best-practice to extract out the underlying imports?
You want to use --importmap
:
Say you add the command line option --importmap @openzeppelin=/opt/openzeppelin-contracts/contracts, then
import "@openzeppelin/interfaces/IERC20.sol";
will automatically map to /opt/openzeppelin-contracts/contracts/interfaces/IERC20.sol.
Thanks for your reply, another silly question that I do think helps a lot in understanding: How can I deploy a contract that interfaces with a previously deployed contract (much like in this example: https://cryptozombies.io/en/lesson/2/chapter/11 )?
Interfaces are supported.
Close to the example you linked would be:
abstract contract NumberInterface {
function getNum(address _myAddress) virtual public view returns (uint);
}
contract Implementor {
function getNum(address _myAddress) public view returns (uint) {
return uint(_myAddress);
}
}
contract MyContract {
function someFunction(address NumberInterfaceAddress) public view returns(uint){
NumberInterface numberContract = NumberInterface(NumberInterfaceAddress);
return numberContract.getNum(msg.sender);
}
}
A bit more idiomatic would be to use an interface
like so:
interface NumberInterface {
function getNum(address _myAddress) view external returns (uint);
}
contract Implementor is NumberInterface {
function getNum(address _myAddress) virtual public view returns (uint) {
return uint(_myAddress);
}
}
contract MyContract {
function someFunction(address NumberInterfaceAddress) public view returns(uint) {
NumberInterface numberContract = NumberInterface(NumberInterfaceAddress);
return numberContract.getNum(msg.sender);
}
}