CRYPTO WALLET DAPP WITH FLUTTER AND SOLIDITY
Tags: flutter, solidity, web3, webdev
Published: 2022-05-21 15:27:35


##Introduction 

The evolution of web3 has been growing at a very fast pace, with a lot of products and tools coming out making it easy to understand and perform transactions on the blockchain. The use of blockchain technologies to develop web apps and mobile apps, also known as decentralised applications (Dapps), like our crypto wallets (trust wallet, metamask), pancake swap, etc., is also growing at a very fast pace. Therefore, anyone who intends to stay current and ahead of the growth should learn how to use and integrate this technology.
 
In this article, I’ll show you how to connect your Solidity smart contract to a flutter application and perform basic CRUD operations. This article is a continuation of my previous article on creating an ERC20 token on a polygon network. In the article, I explain some basic terminologies that won't be repeated in this article, so check it out [Here](https://dev.to/tedtecch/create-an-erc-20-token-on-poygon-3ako).

We’ll cover the following in details: 

- Connecting to a smart contract
- Getting the balance of an address
- Fetching data from the blockchain, e.g., name, symbol, e.t.c.
- Transfer our token from one address to another
- Mint tokens to our address 

###Prerequisites
To understand and follow through this article, you need to have:
- [Flutter](https://flutter.dev) pre-installed
- Basic understanding of flutter and dart
- Code editor
- Web Browser(chrome)

##Getting started 

After writing, compiling, and deploying the smart contract, we need a blockchain server to run it on. There are some platforms that offer this service, like Infura, Alchemy, etc. We will be using Alchemy for its simplicity and also because it provides us access to different blockchain networks.
Simply create an account and create a new app on the platform, enter project details, then you can select the chain, in this case, polygon and network in polygon Mumbai.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j042aoxv521ia45rc24w.png)
 
After creating the app, click on "view key," which would give us a key and two links, as in the image below. You can pick any of the links, but we would use the http link by copying it.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jrvzhsdxcao7flnpoez1.png)

The next thing is to create a new Flutter project and develop a basic design for our app with three buttons: send, receive, and a floating action button (to refresh our screen). The send and receive buttons provide a cupertino alert dialog where we can input an address and amount.
But before we start coding the logic of the app, we need to add some packages.

The first package we require is [web3dart](​​https://pub.dev/packages/web3dart), which is a dart library that connects to the Ethereum blockchain. It connects to an Ethereum node to send transactions, interact with smart contracts, and much more. And the second package is [http](https://pub.dev/packages/http), which is used for making https requests in a flutter.

We start by creating the following variables below. We also paste our metamask address, the http link provided by Alchemy in the blockchain url, and declare a variable `dec`, which represent `10^18` which is the erc20 decimal standard.
```

 late Client httpClient;
  late Web3Client ethClient;
  //Polygon address
  final String myAddress = "0x4818569AA9dE13d3cC1D702Cd10a95932799a674";
  //url from alchemy
  final String blockchainUrl = "https://polygon-mumbai.g.alchemy.com/v2/xhOSAQIFW6H_-NjxcSrpa1vJbwckXTUC";
  bool data = false;
  int myAmount = 0;
  int amt = 0;
  var addressTo = "";
  var dec = pow(10, 18);
  var mydata;
  var mybalance;
  late String transHash;
  var balance;
  var name;
  var symbol;
```
After that, we head back to our **Remix** **IDE**, and in the Solidity compiler tab, we copy the **ABI** of our smart contract as shown in the image below, marked by the **red** arrow. Also, ensure the contract file is our created contract as marked with the **blue** arrow.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wekjexl3tawdu9saqcdc.png)

Then in our flutter project, we create an assets folder in our root folder and within it we create a file named ‘token.json’, in this file, we paste the copied abi. We can then move to our `pubspec.yaml` file and <u>uncomment</u>, adding assets to our application looking like the code below. Then we can run `flutter pub get` command.
```
 assets:
    - assets/
```

In our initState callback, we will initialize our httpClient and Web3client, as well as call a method to retrieve the name, symbol, and balance values from our smart contract:
```
@override
  void initState() {
    httpClient = Client();
    ethClient = Web3Client(blockchainUrl, httpClient);
    super.initState();
    getName();
    getSymbol();
    getBalance(myAddress);
  }
```

###Connect Smart Contract
We declare a contract using the `DeployedContract` class from our `web3dart` package, which takes in the ABI file, the name of our smart contract, which in our case is `FirstToken`, and the contract address and returns it from our function.
```
Future<DeployedContract> getContract() async {
    String abiFile = await rootBundle.loadString("assets/token.json");
    String contractAddress = "0x50338cAF974F2ec1869020e83eF48E36aCE93caf";
    final contract = DeployedContract(
        ContractAbi.fromJson(abiFile, "FirstToken"),
        EthereumAddress.fromHex(contractAddress));
    return contract;
  }
```

###Fetch Data From TheBlockchain
The next function, `query` is used to call a function inside our smart contract, I used it mainly for read operations. This function connects to our smart contract using the call extension from the `web3dart` EthereumClient class, we will be calling this function in another function.
```
Future<List<dynamic>> query(String functionName, List<dynamic> args) async {
    //
    final contract = await getContract();
    final ethFunction = contract.function(functionName);
    // This line below doesn't work.
    final result = await ethClient.call(
        contract: contract, function: ethFunction, params: args);
    // print(result.toString());
    return result;
  }
```

###Write To The Blockchain
In this submit function we are performing a write operation to the blockchain therefore it requires our private key which you can get from metamask, but in a normal wallet, this private key is stored securely in the app when you import or generate a wallet, take note that you should not reveal your private key under any circumstances.

Also, we used a `Transaction.callContract` to pass in our gotten contract, the function we are requesting in our smart contract, the parameters imputed in the function and maximum gas fee, after we used `sendTransaction` from `web3dart` to pass in our private key, the transaction object and `fetchChainIdFromNetworkId`.
```
Future<String> submit(String functionName, List<dynamic> args) async {
    DeployedContract contract = await getContract();
    final ethFunction = contract.function(functionName);
    snackBar(label: "Recording tranction");
    EthPrivateKey key = EthPrivateKey.fromHex(
        "5288***********************************60ffbd08");
    Transaction transaction = await Transaction.callContract(
        contract: contract,
        function: ethFunction,
        parameters: args,
        maxGas: 100000);
    print(transaction.nonce);
    final result = await ethClient.sendTransaction(key, transaction,
        fetchChainIdFromNetworkId: true, chainId: null);
    print(result);
    ScaffoldMessenger.of(context).removeCurrentSnackBar();
    snackBar(label: "verifying transaction");
    //set a 20 seconds delay to allow the transaction to be verified before trying to retrieve the balance
    Future.delayed(const Duration(seconds: 20), () {
      ScaffoldMessenger.of(context).removeCurrentSnackBar();
      snackBar(label: "retriving balance");
      getBalance(myAddress);
      ScaffoldMessenger.of(context).clearSnackBars();
    });
    return result;
  }
```
We set a 20-sec delay before calling our `getBalance` function to ensure that the transaction has been executed because it takes a while, we also add some snackBar to make sure a user knows what is going on.

Moving forward we have the main `getBalance`, `getName` and `getSymbol` function, these functions calls the `query` read request function explained above, pass the function name as it is written in solidity and save it as a variable in our flutter app.
```
Future<void> getBalance(String targetAddress) async {
    EthereumAddress address = EthereumAddress.fromHex(targetAddress);
    // print('In getGreeting');
    List<dynamic> result = await query('balanceOf', [address]);
    print('In getGreeting');
    print(result[0]);
    mybalance = result[0];
    var div = BigInt.from(dec);
    balance = BigInt.from(mybalance / div);
    
    print("balance: $balance");
    data = true;
    setState(() {});
  }
  Future<void> getName() async {
    // print('In getGreeting');
    List<dynamic> result = await query('name', []);
    print(result[0]);
    name = result[0];
    data = true;
    print(name);
    setState(() {});
  }
  Future<void> getSymbol() async {
    List<dynamic> result = await query('symbol', []);
    print(result[0]);
    symbol = result[0];
    data = true;
    setState(() {});
  }
```

Finally, we have our ‘sendCoin’ and ‘recieveCoin’ functions, these functions use the ‘submit’ function explained earlier passing the function name as it is in solidity, also the address it should be sent to and the amount.
```
Future<String> reciveCoin() async {
    EthereumAddress addressTo =
        EthereumAddress.fromHex("0x4818569AA9dE13d3cC1D702Cd10a95932799a674");
    var bigAmount = BigInt.from(myAmount);
    var response = await submit('mint', [addressTo, bigAmount]);
    print('Recieved');
    transHash = response;
    setState(() {});
    return response;
  }
  Future<String> transferCoin() async {
    var amount = BigInt.from(amt *dec);
    EthereumAddress to = EthereumAddress.fromHex(addressTo);
    print("amo: $amount");
    var response = await submit('transfer', [to, amount]);
    print('Transfered');
    transHash = response;
    setState(() {});
    return response;
  }

```
That concludes our logic, when you run your project, you should have something like this.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vir4bofip03jj29s7ozv.gif)
 
##Conclusion
This smart integration has covered enough to help you understand and execute read and write operations to the block chain using flutter which is relatively new, so keep exploring and experimenting. Keep in mind there is no learning without practice.
Check out the link below to access the project's repository.
https://github.com/lyon-zas/ERC-20-wallet