Basically, a smart contract is a set of lines of code registered on the blockchain network. The “contract” comes from the idea of agreements between the related parties, having rules and conditions to materialize a transaction.
But why is it “smart”? Here is a set of reasons why it can be considered smart:
- It is self-executing
- It is immutable
- It is self-verifying
- It is cost-saving
- It removes third parties’ agents
Shall we play with it?
Here, we will use Remix, a web-browser-based-IDE that allows you to write, deploy and run Solidity Smart Contracts.
If you want to run everything locally on your machine, you will need a web page for it, and the contract deployed on an Ethereum network. Take a look at the packages below, as they are the basics for you in this journey:
- Truffle: Development environment, testing framework and asset pipeline for Ethereum;
- Ganache CLI: Simulate full client behavior and make developing Ethereum applications faster, easier, and safer;
- Metamask: It allows you to run Ethereum dApps right in your browser without running a full Ethereum node
- Solidity: Ethereum language for writing Smart Contracts;
- Web3.js: Will allow you to interact with a local or remote Ethereum node, using a HTTP, WebSocket or IPC connection;
- OpenZeppelin: A library for secure smart contract development.
Below, you may find a project on Smart Contracts and Solidity, although I acknowledge it is far from perfect, you’ll get a pretty good idea on how this technology overall works.
The Project
StarNotary is a contract to register stars (in the coding designated as “Star”) — one star is found on the space based on its RA, DEC and MAG (similar to latitude and longitude but specific for the space). If you want to learn more, please check out https://osr.org/locate/.
Bear in mind that there is only one star assigned to one coordinate — this means that duplicate star coordinates cannot be found. Once you register a star in a coordinate, it belongs to you only. Plus, you may also sell it afterwards!
In this project, I used ERC721 (http://erc721.org/) — it ensures that a token is rare and can be owned and negotiable. The full document for this pattern can be found here: https://docs.openzeppelin.com/contracts/2.x/api/token/erc721.
Looking at the code
It is not a good practice to put data and logic together, but in case of study it can be. Look at the declarations below:
struct Star {
string name;
string story;
string ra;
string dec;
string mag;
}
mapping(bytes32 => bool) _tokenExists;
mapping(uint256 => uint256) public starsForSale;
Star[] stars;
The “struct Star” defines the data structure for Stars. Therefore, every Star has a name, a story and its coordinates.
The last line “Star[] stars;” is where all my created Stars are registered.
The mapping “starsForSale” maps the index from array “stars” for a sale price.
The data on Smart Contracts is based on key-value pair, so this is what makes its uniqueness. The “_tokenExists” is a key value pair, and here is where the magic is made to create only one star per coordinate.
The “_tokenExists”will be clearer after looking at the “createStar” method:
function createStar(
string memory _name,
string memory _ra,
string memory _dec,
string memory _mag,
string memory _story)
public
{
bytes32 starHash = _genHash(_ra, _dec, _mag);
require(!_checkIfStarExist(starHash), "This coordinates has already been registered!");
Star memory newStar = Star(_name, _story, _ra, _dec, _mag);
uint256 tokenId = stars.push(newStar) - 1;
// _tokenToIndex[starHash] = tokenId;
_tokenExists[starHash] = true;
mint(msg.sender, tokenId);
emit createStarEvent(tokenId);
}
Once registered, a star never comes out of the contract — it is there forever. You may sell it, but you may not delete it.
On the aforementioned method, note the “starHash” variable — it receives the hash of the star’s coordinates, and this will be the star’s token.
Then the “_tokenExists” maps the token/hash to a simple Boolean true, which defines that the given coordinates, that are already on the chain, cannot be inserted again. What controls the uniqueness of the stars is the line below:
require(!_checkIfStarExist(starHash), "…");
The “require” statement on Solidity is a condition to process, or not, the operation. These kinds of validations can be easily improved using “modifiers”, but the shown example serves its basic purpose.
The “mint” method comes from the extension of ERC721, which basically defines the token’s owner. The “msg.sender” is the blockchain address from the connected wallet. If you use MetaMask, this will become your account address. So, now you own a star and can sell it using the method “putStarUpForSale” by its token, in which you can define the price you want.
The “require” below guarantees that only the owner or approved person can put his stars for sale. This is a requirement of “putStarUpForSale”.
require(_isApprovedOrOwner(msg.sender, _tokenId) == true, "…")
You now have basic knowledge and can make an analysis on the rest of the code by your own.\
Let’s now run it using Remix (https://remix.ethereum.org)
Link for the code: #################################
This is the Remix IDE. The “Files Explorer” is where you will insert the contract; the “.sol” extension for Solidity contracts.
To build the contract, you need a compiler:
Make sure the “Auto Compile” is selected, and that the StarNotary service is selected. This is quite an old project, but it serves this article’s purpose.
We already added the contract and compiled it — now it is time to run it!
In “Environment”, select “JavaScript VM”. Make sure that StarNotary is selected, and then press “Deploy”. If everything works out perfectly, the contract is now deployed on a local chain.
In a basic manner, this is the process to deploy a contract. In a production environment you will probably use commands like “truffle compile” and “truffle migrate” to do it, but Remix can make it in a friendly screen which will facilitate the overall learning experience.
Scrolling down you will see the methods:
You now have a working contract, deployed on the Ethereum blockchain, and can execute any actions through this screen.
Let’s switch onto the “createStar” menu now. Fill the arguments and click on “transact”— if successful, the star will be created. Now try to create another Star with the same coordinates and you will get an error back — remember, we can only have one star per coordinate.
To put it for sale, you will need the StarId — you can get it on the “Results Panel”, which is the result of “createStarEvent”.
Transact away!
Written by Ricardo Valim | Senior Developer at Cleverti