Creating a UI to interact with the smart contract

  1. Create a new file named display_population.dart in the lib/ directory.
  2. Add the following content to the file:

Dart




import 'package:country_pickers/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:population/set_population.dart';
import 'package:provider/provider.dart';
import 'package:population/contract_linking.dart';
  
class DisplayPopulation extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final contractLink = Provider.of<ContractLinking>(context);
  
    return Scaffold(
      appBar: AppBar(
        title: Text("Population On Blockchain"),
        centerTitle: true,
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.edit),
        onPressed: () {
          Navigator.push(
              context,
              MaterialPageRoute(
                  builder: (context) => SetPopulation(),
                  fullscreenDialog: true));
        },
      ),
      body: Container(
        padding: EdgeInsets.symmetric(horizontal: 20),
        child: Center(
          child: contractLink.isLoading
              ? CircularProgressIndicator()
              : SingleChildScrollView(
                  child: Column(
                    children: [
                      contractLink.countryName == "Unknown"
                          ? Icon(
                              Icons.error,
                              size: 100,
                            )
                          : Container(
                              child: CountryPickerUtils.getDefaultFlagImage(
                                  CountryPickerUtils.getCountryByIsoCode(
                                      contractLink.countryName)),
                              width: 250,
                              height: 150,
                            ),
                      Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Text(
                          "Country - ${contractLink.countryName}",
                          style: TextStyle(
                              fontSize: 30,
                              fontWeight: FontWeight.bold,
                              color: Theme.of(context).accentColor),
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Text(
                            "Population - ${contractLink.currentPopulation}",
                            style: TextStyle(
                                fontSize: 25,
                                fontWeight: FontWeight.bold,
                                color: Theme.of(context).primaryColor)),
                      ),
                      contractLink.countryName == "Unknown"
                          ? Text("")
                          : Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: Row(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: [
                                  ElevatedButton.icon(
                                    onPressed: () {
                                      dialog(context, "Increase");
                                    },
                                    icon:
                                        Icon(Icons.person_add_alt_1, size: 18),
                                    label: Text("Increase"),
                                  ),
                                  SizedBox(
                                    width: 15,
                                  ),
                                  ElevatedButton.icon(
                                    onPressed: () {
                                      if (contractLink.currentPopulation !=
                                          "0") {
                                        dialog(context, "Decrease");
                                      }
                                    },
                                    icon: Icon(Icons.person_remove_alt_1,
                                        size: 18),
                                    label: Text("Decrease"),
                                  )
                                ],
                              ),
                            )
                    ],
                  ),
                ),
        ),
      ),
    );
  }
  
  dialog(context, method) {
    final contractLink = Provider.of<ContractLinking>(context, listen: false);
    TextEditingController countController = TextEditingController();
    showDialog(
        context: context,
        builder: (_) => AlertDialog(
              title: method == "Increase"
                  ? Text("Increase Population")
                  : Text("Decrease Population"),
              content: Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                      "Current Population is ${contractLink.currentPopulation}"),
                  Padding(
                    padding: EdgeInsets.only(top: 20.0),
                    child: TextField(
                      controller: countController,
                      keyboardType: TextInputType.number,
                      decoration: InputDecoration(
                        border: OutlineInputBorder(),
                        hintText: method == "Increase"
                            ? "Increase Population By ..."
                            : "Decrease Population By ...",
                      ),
                    ),
                  )
                ],
              ),
              actions: <Widget>[
                Row(
                  children: [
                    TextButton(
                      child: Text("Cancel"),
                      onPressed: () {
                        Navigator.of(context).pop();
                      },
                    ),
                    TextButton(
                      child: method == "Increase"
                          ? Text("Increase")
                          : Text("Decrease"),
                      onPressed: () {
                        method == "Increase"
                            ? contractLink.increasePopulation(
                                int.parse(countController.text))
                            : contractLink.decreasePopulation(
                                int.parse(countController.text));
                        Navigator.of(context).pop();
                      },
                    ),
                  ],
                )
              ],
            ));
  }
}


  1. Create another new file named set_population.dart in the lib/ directory.
  2. Add the following content to the file:

Dart




import 'package:country_pickers/country.dart';
import 'package:country_pickers/country_pickers.dart';
import 'package:flutter/material.dart';
import 'package:population/contract_linking.dart';
import 'package:provider/provider.dart';
  
class SetPopulation extends StatefulWidget {
  @override
  _SetPopulationState createState() => _SetPopulationState();
}
  
class _SetPopulationState extends State<SetPopulation> {
  Country _selectedCountry = CountryPickerUtils.getCountryByIsoCode('AF');
  
  TextEditingController countryNameController =
      TextEditingController(text: "Unknown");
  TextEditingController populationController = TextEditingController();
  
  @override
  Widget build(BuildContext context) {
    final contractLink = Provider.of<ContractLinking>(context);
  
    return Scaffold(
        appBar: AppBar(
          title: Text("Set Population"),
          actions: [
            TextButton(
                onPressed: () {
                  contractLink.addData(countryNameController.text,
                      BigInt.from(int.parse(populationController.text)));
                  Navigator.pop(context);
                },
                child: Text(
                  "SAVE",
                  style: TextStyle(
                      color: Colors.brown, fontWeight: FontWeight.bold),
                ))
          ],
        ),
        body: Container(
          child: Center(
            child: SingleChildScrollView(
              child: Column(
                children: [
                  stackCard(countryFlagPicker(), countryFlag()),
                  stackCard(populationTextfield(), countryFlag()),
                ],
              ),
            ),
          ),
        ));
  }
  
  Widget stackCard(Widget widget1, Widget widget2) {
    return Stack(
      children: [
        Padding(
          padding: EdgeInsets.only(bottom: 8.0, left: 54),
          child: Container(
            height: 120,
            child: Card(
              color: Colors.cyan,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [widget1],
              ),
            ),
          ),
        ),
        widget2
      ],
    );
  }
  
  Widget countryFlag() {
    return Positioned(
      top: 15,
      child: Container(
        width: 100,
        height: 100,
        decoration: BoxDecoration(
          shape: BoxShape.circle,
        ),
        child: CircleAvatar(
            backgroundColor: Colors.blueGrey,
            child: Container(
                width: 80,
                height: 50,
                child:
                    CountryPickerUtils.getDefaultFlagImage(_selectedCountry))),
      ),
    );
  }
  
  Widget countryFlagPicker() {
    return CountryPickerDropdown(
      underline: Container(
        height: 2,
        color: Colors.black,
      ),
      onValuePicked: (Country country) {
        print("${country.name}");
        setState(() {
          _selectedCountry = country;
          countryNameController.text = country.isoCode;
        });
      },
      itemBuilder: (Country country) {
        return Row(
          children: <Widget>[
            SizedBox(width: 48.0),
            CountryPickerUtils.getDefaultFlagImage(country),
            SizedBox(width: 8.0),
            Expanded(
                child: Text(
              country.name,
              style: TextStyle(
                  color: Colors.brown,
                  fontSize: 25,
                  fontWeight: FontWeight.bold),
            )),
          ],
        );
      },
      icon: Icon(
        Icons.arrow_downward,
        color: Colors.white,
        size: 50,
      ),
      itemHeight: null,
      isExpanded: true,
    );
  }
  
  Widget populationTextfield() {
    return Padding(
      padding: EdgeInsets.only(left: 48.0, right: 5),
      child: TextField(
        decoration: InputDecoration(
            filled: true,
            fillColor: Colors.black,
            focusedBorder: OutlineInputBorder(),
            labelText: "Population",
            labelStyle: TextStyle(color: Colors.white),
            hintText: "Enter Population",
            prefixIcon: Icon(Icons.person_pin_outlined)),
        keyboardType: TextInputType.number,
        controller: populationController,
      ),
    );
  }
}


  • Update the main.dart as :

Dart




import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:population/display_population.dart';
import 'package:provider/provider.dart';
import 'package:population/contract_linking.dart';
  
void main() => runApp(MyApp());
  
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<ContractLinking>(
      create: (_) => ContractLinking(),
      child: MaterialApp(
        title: 'Population On Blockchain',
        theme: ThemeData(
            brightness: Brightness.dark,
            primaryColor: Colors.cyan[400],
            accentColor: Colors.deepOrange[200]),
        home: DisplayPopulation(),
      ),
    );
  }
}


Flutter and Blockchain – Population Dapp

Before checking out this article, Do take a look at Flutter and Blockchain – Hello World Dapp. This tutorial will take you through the process of building your mobile dapp – Population on Blockchain!

This tutorial is meant for those with a basic knowledge of Ethereum and smart contracts, who have some knowledge of the Flutter framework but are new to mobile dapps.

In this tutorial we will be covering:

  1. Setting up the development environment
  2. Creating a Truffle Project
  3. Writing the Smart Contract
  4. Compiling and Migrating the Smart Contract
  5. Testing the Smart Contract
  6. Contract linking with Flutter
  7. Creating a UI to interact with the smart contract
  8. Interacting with the complete Dapp

Description

Population on blockchain is a simple decentralized application, which will allow you to store a specific country population on the blockchain, you can increment as well as decrement the population based on the current condition of the country.

Output:

Similar Reads

Setting up the development environment

Truffle is the most popular development framework for Ethereum with a mission to make your life a whole lot easier. But before we install truffle make sure to install node ....

Creating a Truffle Project

Create a basic Flutter project in your favorite IDE Initialize Truffle in the flutter project directory by running...

Writing the Smart Contract

The Smart Contract actually acts as the back-end logic and storage for our Dapp....

Compiling and Migrating

...

Testing the Smart Contract

...

Contract linking with Flutter

...

Creating a UI to interact with the smart contract

...

Interacting with the complete Dapp

Compilation...