FISCO BCOS | Aufbau der ersten Blockchain-Anwendung

In diesem Kapitel wird der gesamte Prozess der Entwicklung von Geschäftsanwendungsszenarien basierend auf der FISCO BCOS-Blockchain vorgestellt. Die Einführung umfasst Geschäftsszenarioanalyse, Vertragsgestaltung und -umsetzung, Vertragserstellung, Blockchain-Entwicklung usw. Abschließend stellen wir eine Anwendungsmodulimplementierung vor, die das Aufrufen und Zugreifen auf Verträge in der Blockchain über das von uns bereitgestellte Java SDK implementiert.

Für dieses Tutorial müssen Benutzer mit der Linux-Betriebssystemumgebung vertraut sein, über grundlegende Kenntnisse in der Java-Entwicklung verfügen, das Gradle-Tool verwenden können und mit der Solidity-Syntax vertraut sein.

Durch dieses Tutorial lernen Sie Folgendes:

  1. Wie man die Logik von Geschäftsszenarien in Form eines Vertrags ausdrückt
  2. So konvertieren Sie einen Solidity-Vertrag in eine Java-Klasse
  3. So konfigurieren Sie das Java Development Kit
  4. So erstellen Sie eine Anwendung und integrieren das Java SDK in die Anwendungsentwicklung
  5. So rufen Sie die Vertragsschnittstelle über das Java SDK auf und verstehen ihr Prinzip

Der vollständige Projektquellcode für dieses Beispiel wird in diesem Tutorial bereitgestellt, und Benutzer können darauf basierend schnell ihre eigenen Anwendungen entwickeln.

Beispielanforderungen für Bewerbungen

Blockchain ist von Natur aus manipulationssicher und rückverfolgbar. Diese Merkmale machen es für den Finanzsektor attraktiver. Dieser Artikel bietet ein einfaches Beispiel für die Entwicklung des Asset Managements und erreicht letztendlich die folgenden Funktionen:

  • Möglichkeit, Vermögenswerte in der Blockchain zu registrieren
  • Möglichkeit, Gelder von verschiedenen Konten zu überweisen
  • Möglichkeit, die Höhe der Vermögenswerte auf einem Konto zu überprüfen

Vertragsgestaltung und -umsetzung

Bei der Entwicklung von Anwendungen auf der Blockchain müssen Sie zur Kombination von Geschäftsanforderungen zunächst den entsprechenden Smart-Vertrag entwerfen, die für den Vertrag erforderlichen Speicherdaten bestimmen und auf dieser Grundlage die vom Smart-Vertrag bereitgestellte Schnittstelle bestimmen. Implementieren Sie abschließend jede Schnittstelle speziell.

existent 储设计

FISCO BCOS bietet ein Vertrags-CRUD-Schnittstellenentwicklungsmodell, mit dem Tabellen über Verträge erstellt und die erstellten Tabellen hinzugefügt, gelöscht und geändert werden können. Für diese Anwendung müssen wir eine Tabelle zum Speichern der Vermögensverwaltung entwerfen. Die Felder dieser Tabelle lauten wie folgt: t_asset

  • Konto: Primärschlüssel, Vermögenskonto (String-Typ)
  • asset_value: Vermögenswert (Typ UINT256)

Konto ist der Primärschlüssel und ein Feld, das beim Betrieb der Tabelle übergeben werden muss. Die Blockchain fragt die Tabelle nach übereinstimmenden Datensätzen basierend auf dem Primärschlüsselfeld ab. Ein Beispiel für eine Tabelle ist: t_assett_asset

Bild

Schnittstellendesign

Entsprechend den Designzielen des Unternehmens müssen Funktionen zur Registrierung, Übertragung und Abfrage von Vermögenswerten implementiert werden. Die Schnittstelle der entsprechenden Funktion lautet wie folgt:

// query the amount of assets
function select(string account) public constant returns(int256, uint256)
// asset registration
function register(string account, uint256 amount) public returns(int256)
// asset transfer
function transfer(string from_asset_account, string to_asset_account, uint256 amount) public returns(int256)

Perfekter Ursprung

pragma solidity ^0.4.24;


import "./Table.sol";


contract Asset {
    // event
    event RegisterEvent(int256 ret, string account, uint256 asset_value);
    event TransferEvent(int256 ret, string from_account, string to_account, uint256 amount);


    constructor() public {
        // create a t_asset table in the constructor
        createTable();
    }


    function createTable() private {
        TableFactory tf = TableFactory(0x1001);
        // asset management table, key : account, field : asset_value
        // |  account(primary key)   |  amount       |
        // |-------------------- |-------------------|
        // |        account      |    asset_value    |
        // |---------------------|-------------------|
        //
        // create table
        tf.createTable("t_asset", "account", "asset_value");
    }


    function openTable() private returns(Table) {
        TableFactory tf = TableFactory(0x1001);
        Table table = tf.openTable("t_asset");
        return table;
    }


    /*
    description: query asset amount according to asset account


    parameter:
            account: asset account


    return value:
            parameter1: successfully returns 0, the account does not exist and returns -1
            parameter2: valid when the first parameter is 0, the amount of assets
    */
    function select(string account) public constant returns(int256, uint256) {
        // open table
        Table table = openTable();
        // query
        Entries entries = table.select(account, table.newCondition());
        uint256 asset_value = 0;
        if (0 == uint256(entries.size())) {
            return (-1, asset_value);
        } else {
            Entry entry = entries.get(0);
            return (0, uint256(entry.getInt("asset_value")));
        }
    }


    /*
    description : asset registration
    parameter :
            account : asset account
            amount  : asset amount
    return value:
            0  regist successfully
            -1 asset account already exists
            -2 other error
    */
    function register(string account, uint256 asset_value) public returns(int256){
        int256 ret_code = 0;
        int256 ret= 0;
        uint256 temp_asset_value = 0;
        // to query whather the account exists
        (ret, temp_asset_value) = select(account);
        if(ret != 0) {
            Table table = openTable();


            Entry entry = table.newEntry();
            entry.set("account", account);
            entry.set("asset_value", int256(asset_value));
            // insert
            int count = table.insert(account, entry);
            if (count == 1) {
                // true
                ret_code = 0;
            } else {
                // false. no permission or other error
                ret_code = -2;
            }
        } else {
            // account already exists
            ret_code = -1;
        }


        emit RegisterEvent(ret_code, account, asset_value);


        return ret_code;
    }


    /*
    description : asset transfer
    parameter :
            from_account : transferred asset account
            to_account :received asset account
            amount : transferred amount
    return value:
            0  transfer asset successfully
            -1 transfe asset account does not exist
            -2 receive asset account does not exist
            -3 amount is insufficient
            -4 amount is excessive
            -5 other error
    */
    function transfer(string from_account, string to_account, uint256 amount) public returns(int256) {
        // query transferred asset account information
        int ret_code = 0;
        int256 ret = 0;
        uint256 from_asset_value = 0;
        uint256 to_asset_value = 0;


        // whather transferred asset account exists?
        (ret, from_asset_value) = select(from_account);
        if(ret != 0) {
            ret_code = -1;
            // not exist
            emit TransferEvent(ret_code, from_account, to_account, amount);
            return ret_code;


        }


        // whather received asset account exists?
        (ret, to_asset_value) = select(to_account);
        if(ret != 0) {
            ret_code = -2;
            // not exist
            emit TransferEvent(ret_code, from_account, to_account, amount);
            return ret_code;
        }


        if(from_asset_value < amount) {
            ret_code = -3;
            // amount of transferred asset account is insufficient
            emit TransferEvent(ret_code, from_account, to_account, amount);
            return ret_code;
        }


        if (to_asset_value + amount < to_asset_value) {
            ret_code = -4;
            // amount of received asset account is excessive
            emit TransferEvent(ret_code, from_account, to_account, amount);
            return ret_code;
        }


        Table table = openTable();


        Entry entry0 = table.newEntry();
        entry0.set("account", from_account);
        entry0.set("asset_value", int256(from_asset_value - amount));
        // update transferred account
        int count = table.update(from_account, entry0, table.newCondition());
        if(count != 1) {
            ret_code = -5;
            // false? no permission or other error?
            emit TransferEvent(ret_code, from_account, to_account, amount);
            return ret_code;
        }


        Entry entry1 = table.newEntry();
        entry1.set("account", to_account);
        entry1.set("asset_value", int256(to_asset_value + amount));
        // update received account
        table.update(to_account, entry1, table.newCondition());


        emit TransferEvent(ret_code, from_account, to_account, amount);


        return ret_code;
    }
}

Hinweis:Die Umsetzung des Vertrags erfordert die Einführung der von FISCO BCOS bereitgestellten Systemvertragsschnittstellendatei. Die Schnittstelle der Systemvertragsdatei wird durch das zugrunde liegende FISCO BCOS implementiert. Wenn der Geschäftsvertrag den Betrieb der CRUD-Schnittstelle erfordert, muss die Schnittstellenvertragsdatei eingeführt werden. Die detaillierte Schnittstellenreferenz des Vertrags finden Sie hier:

​https://fisco-bcos-documentation.readthedocs.io/en/latest/docs/manual/smart_contract.html#crud​

Asset.solTable.solTable.sol

Gemeinsame Vereinbarung

Im vorherigen Abschnitt haben wir die Speicherung und Schnittstelle des Vertrags basierend auf den Geschäftsanforderungen entworfen und vollständig implementiert. Allerdings können Java-Programme Solidity-Verträge nicht direkt aufrufen. Solidity-Vertragsdateien müssen zuerst in Java-Dateien kompiliert werden. Asset.sol

Die Konsole bietet ein Kompilierungstool zum Speichern von Vertragsdateien in einem Verzeichnis. Kompilieren Sie mit dem im Konsolenverzeichnis bereitgestellten Skript wie folgt:

Asset.solconsole/contract/soliditysol2java.sh

$ mkdir -p ~/fisco
# download console
$ cd ~/fisco && curl -#LO https://github.com/FISCO-BCOS/console/releases/download/v2.9.2/download_console.sh && bash download_console.sh
# switch to the fisco/console/ directory
$ cd ~/fisco/console/
# compile the contract, specify a Java package name parameter later, you can specify the package name according to the actual project path.
$ ./sol2java.sh -p org.fisco.bcos.asset.contract

Nach erfolgreichem Vorgang werden die Verzeichnisse Java, ABI und Bin wie unten gezeigt generiert. console/contracts/sdkdirectory

|-- abi # The generated abi directory, which stores the abi file generated by Solidity contract compilation.
|   |-- Asset.abi
|   |-- Table.abi
|-- bin # The generated bin directory, which stores the bin file generated by Solidity contract compilation.
|   |-- Asset.bin
|   |-- Table.bin
|-- contracts # The source code file that stores Solidity contract. Copy the contract that needs to be compiled to this directory.
|   |-- Asset.sol # A copied Asset.sol contract, depends on Table.sol
|   |-- Table.sol # The contract interface file that implements the CRUD operation
|-- java  # Storing compiled package path and Java contract file
|   |-- org
|        |--fisco
|             |--bcos
|                  |--asset
|                       |--contract
|                             |--Asset.java  # Java file generated by the Asset.sol contract
|                             |--Table.java  # Java file generated by the Table.sol contract
|-- sol2java.sh

Das Paketpfadverzeichnis wird im Java-Verzeichnis generiert. Dieses Verzeichnis enthält zwei Dateien und , die von der Java-Anwendung zum Aufrufen des Asset.sol-Vertrags benötigt werden.

org/fisco/bcos/asset/contract/Asset.javaTable.javaAsset.java

Die Hauptschnittstelle von Asset.java:

package org.fisco.bcos.asset.contract;


public class Asset extends Contract {
    // Asset.sol contract  transfer interface generation
    public TransactionReceipt transfer(String from_account, String to_account, BigInteger amount);
    // Asset.sol contract  register interface generation
    public TransactionReceipt register(String account, BigInteger asset_value);
    // Asset.sol contract  select interface generation
     public Tuple2<BigInteger, BigInteger> select(String account) throws ContractException;


    // Load the Asset contract address, to generate Asset object
    public static Asset load(String contractAddress, Client client, CryptoKeyPair credential);


    // Deploy Assert.sol contract, to generate Asset object
    public static Asset deploy(Client client, CryptoKeyPair credential) throws ContractException;
}

Die Lade- und Bereitstellungsfunktionen werden zum Erstellen von Asset-Objekten verwendet, und andere Schnittstellen werden zum Aufrufen der Schnittstellen des entsprechenden Soliditätsprotokolls verwendet. Die spezifische Verwendung wird im Folgenden vorgestellt.

Development Kit-Konfiguration

Wir stellen ein Java-Projekt zur Entwicklung bereit. Holen Sie sich zunächst das Java-Projekt:

$ mkdir -p ~/fisco
# get the Java project project archive
$ cd ~/fisco
$ curl -#LO https://github.com/FISCO-BCOS/LargeFiles/raw/master/tools/asset-app.tar.gz
# extract the Java project project asset-app directory
$ tar -zxf asset-app.tar.gz

Wenn das Asset app.tar.gz aufgrund von Netzwerkproblemen längere Zeit nicht heruntergeladen werden kann, versuchen Sie es bitte mit:

curl-#LOhttps://osp-1257653870.cos.ap-guangzhou.myqcloud.com/FISCO-BCOS/FISCO-BCOS/tools/asset-app.tar.gz

Die Verzeichnisstruktur des Asset-Anwendungsprojekts ist wie folgt:

|-- build.gradle // gradle configuration file
|-- gradle
|   |-- wrapper
|       |-- gradle-wrapper.jar //  related code implementation for downloading Gradle
|       |-- gradle-wrapper.properties //  Configuration information used by the wrapper, such as the version of gradle
|-- gradlew // shell script for executing wrapper commands under Linux or Unix
|-- gradlew.bat // batch script for executing wrapper commands under Windows
|-- src
|   |-- main
|   |   |-- java
|   |         |-- org
|   |             |-- fisco
|   |                   |-- bcos
|   |                         |-- asset
|   |                               |-- client // the client calling class
|   |                                      |-- AssetClient.java
|   |                               |-- contract // the Java contract class
|   |                                      |-- Asset.java
|   |-- test
|       |-- resources // resource files
|           |-- applicationContext.xml // project configuration file
|           |-- contract.properties // file that stores the deployment contract address
|           |-- log4j.properties // log configuration file
|           |-- contract // Solidity contract files
|                   |-- Asset.sol
|                   |-- Table.sol
|
|-- tool
    |-- asset_run.sh // project running script

ProjekteinführungJava SDK

Die Dateien dieses Projekts wurden in das Java SDK eingeführt und müssen nicht geändert werden. Die Einführungsmethode ist wie folgt:

  • Sie müssen das Maven-Remote-Repository zur Datei hinzufügen: build.gradle
repositories {
    mavenCentral()
    maven {
        url "http://maven.aliyun.com/nexus/content/groups/public/"
    }
    maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
}

  • Vorstellung des Java SDK-JAR-Pakets
compile ('org.fisco-bcos.java-sdk:fisco-bcos-java-sdk:2.7.2')

Zertifikate und Konfigurationsdateien

  • Konfiguration des Blockchain-Knotenzertifikats

Kopieren Sie das SDK-Zertifikat, das dem Blockchain-Knoten entspricht

# go to the ~ directory
# copy the node certificate to the project's resource directory
$ cd ~/fisco
$ cp -r nodes/127.0.0.1/sdk/* asset-app/src/test/resources/conf
# if you want to run this app in IDE, copy the certificate to the main resource directory
$ mkdir -p asset-app/src/main/resources/conf
$ cp -r nodes/127.0.0.1/sdk/* asset-app/src/main/resources/conf

  • Anwendungskontext.xml

Hinweis:

Wenn der in der Kette festgelegte Kanal_Listen_IP (wenn die Knotenversion niedriger als v2.3.0 ist, überprüfen Sie Listen_IP) 127.0.0.1 oder 0.0.0.0 ist und der Kanal_Listen_Port 20200 ist, besteht keine Notwendigkeit, die Konfiguration zu ändern. Wenn sich die Konfiguration des Blockchain-Knotens ändert, muss sie geändert werden.

applicationContext.xmlapplicationContext.xml

Geschäftsausstellung

Wir haben erläutert, wie Sie das Java SDK in Ihrem eigenen Projekt einführen und konfigurieren. In diesem Abschnitt wird beschrieben, wie der Vertrag über ein Java-Programm aufgerufen wird, sowie eine Beispielanweisung für die Vermögensverwaltung. Das Asset-Anwendungsprojekt enthält bereits den vollständigen Quellcode des Beispiels, den Benutzer direkt verwenden können. Stellen Sie nun das Design und die Implementierung der Kernklassen vor. AssetClient

AssetClient.java: Die Bereitstellung und der Aufruf des Vertrags werden durch Aufruf implementiert. Der Pfad, die Initialisierung und der Aufrufprozess befinden sich alle in dieser Klasse.

Asset.java/src/main/java/org/fisco/bcos/asset/client

  • Initialisierung

Die Hauptfunktion des Initialisierungscodes besteht darin, Web3j- und Anmeldeinformationsobjekte zu erstellen, die beim Erstellen der entsprechenden Vertragsklassenobjekte benötigt werden (Aufruf der Bereitstellungs- oder Ladefunktion der Vertragsklasse).

@SuppressWarnings("resource")
ApplicationContext context =
        new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
bcosSDK = context.getBean(BcosSDK.class);
// init the client that can send requests to the group one
client = bcosSDK.getClient(1);
// create the keyPair
cryptoKeyPair = client.getCryptoSuite().createKeyPair();
client.getCryptoSuite().setCryptoKeyPair(cryptoKeyPair);
logger.debug("create client for group1, account address is " + cryptoKeyPair.getAddress());

  • Konstruieren Sie ein Vertragsklassenobjekt

Vertragsobjekte können über Deployment- oder Ladefunktionen initialisiert werden, die in verschiedenen Szenarien zum Einsatz kommen. Ersteres eignet sich für die erstmalige Bereitstellung des Vertrags, letzteres wird verwendet, wenn der Vertrag bereitgestellt wurde und die Vertragsadresse bekannt ist.

// deploy contract
Asset asset = Asset.deploy(client, cryptoKeyPair);
// load contract address
Asset asset = Asset.load(contractAddress, client, cryptoKeyPair);

  • Schnittstellenaufruf

Verwenden Sie das Vertragsobjekt, um die entsprechende Schnittstelle aufzurufen und die zurückgegebenen Ergebnisse zu verarbeiten.

// select interface calling
 Tuple2<BigInteger, BigInteger> result = asset.select(assetAccount);
// register interface calling
TransactionReceipt receipt = asset.register(assetAccount, amount);
// transfer interface
TransactionReceipt receipt = asset.transfer(fromAssetAccount, toAssetAccount, amount);

läuft

Bisher haben wir alle Prozesse eingeführt und die Funktionen einer Asset-Management-Anwendung mithilfe der Blockchain implementiert. Anschließend können wir das Projekt ausführen und testen, ob die Funktion ordnungsgemäß funktioniert.

  • Zusammenstellung
# switch to project directory
$ cd ~/asset-app
# compile project
$ ./gradlew build

Nach erfolgreicher Kompilierung wird ein Verzeichnis im Projektstammverzeichnis generiert. Im dist-Verzeichnis befindet sich ein Skript, um den Projektbetrieb zu vereinfachen. Lassen Sie uns nun zunächst die in diesem Artikel aufgeführten Anforderungen überprüfen. distasset_run.sh

  • Stellen Sie den Asset.sol-Vertrag bereit
# enter dist directory
$ cd dist
$ bash asset_run.sh deploy
Deploy Asset successfully, contract address is 0xd09ad04220e40bb8666e885730c8c460091a4775
  • Vermögenswerte registrieren
$ bash asset_run.sh register Alice 100000
Register account successfully => account: Alice, value: 100000
$ bash asset_run.sh register Bob 100000
Register account successfully => account: Bob, value: 100000
  • Assets abfragen
$ bash asset_run.sh query Alice
account Alice, value 100000
$ bash asset_run.sh query Bob
account Bob, value 100000

  • Vermögenswerte übertragen
$ bash asset_run.sh transfer Alice Bob  50000
Transfer successfully => from_account: Alice, to_account: Bob, amount: 50000
$ bash asset_run.sh query Alice
account Alice, value 50000
$ bash asset_run.sh query Bob
account Bob, value 150000

Zusammenfassung:Bisher haben wir Anwendungen basierend auf der Blockchain der FISCO BCOS Alliance durch Vertragsentwicklung, Vertragskompilierung, SDK-Konfiguration und Geschäftsentwicklung erstellt.

Supongo que te gusta

Origin blog.csdn.net/BSN_yanxishe/article/details/133788585
Recomendado
Clasificación