Using Aurora to deploy an Ethereum smart contract
In this tutorial, we'll walk through the flow for deploying a smart contract to Aurora, and discuss how Ethereum and NEAR can be used to interact with this smart contract.
In this tutorial, we are going to deploy an ERC-721 smart contract to Aurora testnet, and will be reproducing some of the steps used in the Deploying a Contract using Truffle Aurora Tutorial. Parts of this tutorial will be modified to use the Aurora testnet endpoints available via Infura.
Once the smart contract is deployed, we can bridge ETH or NEAR to Aurora, and use that bridged ETH and NEAR to pay for gas costs associated with minting tokens using the ERC-721 contract we have created. This example meant to illustrate how Aurora can be used to cheaply deploy a smart contract. Similar patterns could be used for DeFi applications (if using an ERC-20 token), DAO membership, gaming, and other use cases.
At this time, tokens that are minted on Ethereum can use the Rainbow Bridge to move to Aurora. Tokens minted on NEAR can also be bridged to Aurora using the Rainbow Bridge. At this time, tokens created on Aurora cannot yet be bridged to Ethereum or NEAR, but this is on the roadmap for Aurora.
Tokens minted on Aurora are not able to bridged to Ethereum or NEAR at this time.

Deploy an ERC-721 smart contract to Aurora testnet

This tutorial assumes familiarity and prior usage of the smart contract development suite Truffle. If this is your first use of Truffle, we recommend completing the "Pet Shop" tutorial in the Truffle documentation first before starting on this tutorial.

1. Create a project directory and initialize a Truffle project

In your terminal, create a new folder called aurora-721-example and initialize a truffle project within that directory
1
mkdir aurora-721-example
2
cd aurora-721-example
3
truffle init
Copied!

2. Download the OpenZeppelin contracts

Within the aurora-721-example directory, download the OpenZeppelin contracts, as the smart contract we will deploy will import some of these contracts.
1
npm install @openzeppelin/contracts
Copied!

3. Create an account to sign transactions

In order to sign transactions, we'll need an account to sign with. There are multiple ways to generate a wallet, and if this is your first time doing so, we encourage you to follow Step 3 of the ConsenSys Developer Portal. Alternatively, you can use Truffle Dashboard to connect an existing wallet and sign transactions without needing to put your mnemonic in a .env file.

4. Create the .env file

As we are using a .env file to store our Infura project ID, run following command in your terminal:
1
npm install --save dotenv
Copied!
Create a file in the root level of your directory called .env and inside this file enter the following information, providing your Infura project ID, and, if needed, your mnemonic
1
INFURA_API_KEY=INSERT YOUR INFURA PROJECT ID HERE WITHOUT QUOTATIONS
2
MNEMONIC=”if you are using a mnemonic associated with a wallet it will go here”
Copied!
NEVER PUSH A .env FILE TO GITHUB OR ANY PUBLIC LOCATION. For best practices on using a .env file and protecting your secrets as it relates to Infura please read How to Use .env to Enhance Basic Security Within Your DApp. General advice on protecting your secrets can found by reading at How to Avoid Uploading Your Private Keys to GitHub

5. Create your smart contract

Navigate to the Contracts folder and create a new contract called ClubToken.sol. Within that file, paste the following code:
1
SPDX-License-Identifier: MIT
2
pragma solidity ^0.8.0;
3
4
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
5
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
6
import "@openzeppelin/contracts/utils/Counters.sol";
7
8
contract ClubToken is ERC721URIStorage {
9
uint256 private _tokensCount = 0;
10
address public minter = address(0);
11
12
modifier onlyMinter(){
13
require(
14
minter == msg.sender,
15
'Invalid Minter'
16
);
17
_;
18
}
19
20
constructor() ERC721("ClubToken", "CT") {
21
minter = msg.sender;
22
}
23
24
function mint(address to) external onlyMinter {
25
uint256 tokenId = _tokensCount + 1;
26
_mint(to, tokenId);
27
_tokensCount = tokenId;
28
}
29
30
function burn(uint256 tokenId) external {
31
_burn(tokenId);
32
_tokensCount -= 1;
33
}
34
35
function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
36
require(minter == msg.sender || to == minter, 'Invalid Transfer');
37
safeTransferFrom(from, to, tokenId, "");
38
}
39
40
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {
41
require(minter == msg.sender || to == minter, 'Invalid Transfer');
42
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
43
_safeTransfer(from, to, tokenId, _data);
44
}
45
}
Copied!

6. Create the migrations script

Navigate to the migrations folder and create a file named 2_deploy_contracts.js and paste in the following code:
1
const ClubToken = artifacts.require("ClubToken.sol");
2
3
module.exports = function(deployer) {
4
deployer.deploy(ClubToken);
5
};
Copied!

7. Configure the Truffle settings

Now navigate to the truffle-config.js file and put the following information at the top of the file, assuming you are using a .env to store your Infura project ID and wallet mnemonic:
1
require("dotenv").config();
2
const HDWalletProvider = require("@truffle/hdwallet-provider");
Copied!
Under the networks section of truffle-config.js paste in the following code:
1
auroratestnet: {
2
provider: () =>
3
new HDWalletProvider(
4
process.env.MNEMONIC,
5
`https://aurora-testnet.infura.io/v3/${process.env.INFURA_API_KEY}`
6
),
7
network_id: 0x4e454153, // Aurora testnet ID
8
gas: 10000000
9
},
Copied!
Save this file. We will now use Truffle to deploy this smart contract to Aurora testnet.

8. Compile and deploy the smart contract to Aurora testnet

In your terminal, run the command:
1
truffle migrate --network auroratestnet
Copied!
This will compile and migrate the smart contract to the Aurora testnet, and you will be able to see the deployed code using the testnet version of Aurorascan. We now have deployed a smart contract to Aurora testnet.
1
Compiling your contracts...
2
===========================
3
> Compiling ./contracts/ClubToken.sol
4
> Artifacts written to /Users/Code/aurora-721-example/build/contracts
5
> Compiled successfully using:
6
- solc: 0.8.11+commit.d7f03943.Emscripten.clang
7
8
9
Starting migrations...
10
======================
11
> Network name: 'auroratestnet'
12
> Network id: 1313161555
13
> Block gas limit: 0 (0x0)
14
15
16
2_deploy_contracts.js
17
=====================
18
19
Deploying 'ClubToken'
20
-------------------------------
21
> transaction hash: 0xe999cf28b54d11985f61d33aeb8cd11c269a45bdd28f389ad0ebb83101fddc4e
22
> Blocks: 11 Seconds: 8
23
> contract address: 0x12820Dc1283354CbB9f2478b6c044d4260E95e15
24
> block number: 84998829
25
> block timestamp: 1647289263
26
> account: 0xc94C5473073878FAFd500aFfb5495aDb2230Eeea
27
> balance: 0.001
28
> gas used: 2685442 (0x28fa02)
29
> gas price: 0 gwei
30
> value sent: 0 ETH
31
> total cost: 0 ETH
32
33
> Saving migration to chain.
34
> Saving artifacts
35
-------------------------------------
36
> Total cost: 0 ETH
37
38
Summary
39
=======
40
> Total deployments: 1
41
> Final cost: 0 ETH
Copied!
The Aurora documentation provides sample code to deploy dapps and move tokens between Ethereum and Aurora.