Vern  Greenholt

Vern Greenholt

1594090500

Day 15: Manipulate filenames with the least amount of clicking

To guarantee your analysis is streamlined and repeatable, get acquainted with the function regexprep.

On Day 13 and Day 14, we used regular expressions to locate text. In today’s post, we use regular expressions within the function regexprep, which is the key to making precise and effective text substitutions.

Here are a few simple use cases for regexprep:

Removing characters from filenames. In the interest of consistency, it’s great if you can take a set of data with a filename and turn that filename into a figure title. Here’s how you might do it.

% Lets suppose we have a file with some data %
file = 'C:\Files\Kaleemah\Mouse1\Images\Neuron_10_May_12_Dorsal.tif'

% We would load the file and show the image %

Now you want to create a title but you don’t want all that extra stuff. Here’s how to do it in two steps. First, make sure you feel comfortable with the topics I cover in Day 13 and Day 14. Next, we’ll just get the filename:

% Extract just the filename %

file = regexp( file, '(Neuron.*)(?=.tif)', 'match')
file = file{1}

Aside: Yes there’s a far more sophisticated way of doing this, which I have not covered yet because as I’ve said, regular expressions can become very complex and I suggest that if you have the time and patience, you spend a few weeks on them. Here is the alternative approach:

file = 'C:\Files\Kaleemah\Mouse1\Images\Neuron_10_May_12_Dorsal.tif'
file = regexp( file, '([^\\]+$)', 'match')
file = regexp( file, '(.*)(?=.tif)', 'match')

% To recover the output as a string you'll need to use file{1}{1} %

In either case, at this point, you should have a variable _file _which is a string containing: ‘Neuron_10_May_12_Dorsal’

Now if you tried to create a figure and title a plot, whether it’s through the _axes _or _title _function, you will run into this issue:

Here’s how to use _regexprep _to get around this:

file = regexprep( file, '_', ' ' )

If you then title the plot, you will see the text rendered without the subscripts.

#matlab #data #analysis #neuroscience #text-mining #data analysis

What is GEEK

Buddha Community

Day 15: Manipulate filenames with the least amount of clicking
Vern  Greenholt

Vern Greenholt

1594090500

Day 15: Manipulate filenames with the least amount of clicking

To guarantee your analysis is streamlined and repeatable, get acquainted with the function regexprep.

On Day 13 and Day 14, we used regular expressions to locate text. In today’s post, we use regular expressions within the function regexprep, which is the key to making precise and effective text substitutions.

Here are a few simple use cases for regexprep:

Removing characters from filenames. In the interest of consistency, it’s great if you can take a set of data with a filename and turn that filename into a figure title. Here’s how you might do it.

% Lets suppose we have a file with some data %
file = 'C:\Files\Kaleemah\Mouse1\Images\Neuron_10_May_12_Dorsal.tif'

% We would load the file and show the image %

Now you want to create a title but you don’t want all that extra stuff. Here’s how to do it in two steps. First, make sure you feel comfortable with the topics I cover in Day 13 and Day 14. Next, we’ll just get the filename:

% Extract just the filename %

file = regexp( file, '(Neuron.*)(?=.tif)', 'match')
file = file{1}

Aside: Yes there’s a far more sophisticated way of doing this, which I have not covered yet because as I’ve said, regular expressions can become very complex and I suggest that if you have the time and patience, you spend a few weeks on them. Here is the alternative approach:

file = 'C:\Files\Kaleemah\Mouse1\Images\Neuron_10_May_12_Dorsal.tif'
file = regexp( file, '([^\\]+$)', 'match')
file = regexp( file, '(.*)(?=.tif)', 'match')

% To recover the output as a string you'll need to use file{1}{1} %

In either case, at this point, you should have a variable _file _which is a string containing: ‘Neuron_10_May_12_Dorsal’

Now if you tried to create a figure and title a plot, whether it’s through the _axes _or _title _function, you will run into this issue:

Here’s how to use _regexprep _to get around this:

file = regexprep( file, '_', ' ' )

If you then title the plot, you will see the text rendered without the subscripts.

#matlab #data #analysis #neuroscience #text-mining #data analysis

Integrate Stratis Blockchain APIs In Your Custom Application

In this article, I will elucidate how to integrate Stratis Blockchain API in custom or third-party applications. We will create an angular application and integrate Stratis Private APIs. We will interact with Stratis Blockchain APIs and show the response in the custom application. Additionally, this article will describe creating a user interface to deploy the Smart Contract. This write-up explains and provides the code for all endpoints necessary for deploying the Smart Contract; however, you can get ideas and interact with any other endpoints according to your custom software requirement. For more details on how to write Smart Contract and generate byte code, you can visit here.

The source code is available here.

Prerequisites

  • IDE for Angular (Visual Studio or Visual Studio Code) as per you
  • Stratis FullNode
  • Smart Contract Byte Code

For this article, we will be using angular 12, however, it will be the same for another version as well.

Create Angular Application

We will create an angular application with angular CLI as shown below steps,

Install Angular CLI ( if you don’t have it).

npm install -g @angular/cli

Bash

We will create a new app with the following command,

ng new StratisFullNodeWebApp

JavaScript

We will navigate to the project folder and run the application. To build and run the angular application we use the serve command as shown.

cd StratisFullNodeWebApp
ng serve

Bash

Alternatively, to open the default Angular Application: Run below command which builds, run and open at once.

ng serve --open

Bash

The –open command opens a project to the browser at http://localhost:4200/To design lucrative UI, I have implemented the AdminLTE theme. If you want, you can also implement it following steps from here.

Create and Add Model in Angular App

Create _model folder where we will keep all the models for each component.

We can add the model using the command and also manually as described below: In _model folder right-click–> add a new item –> Add typescript File and rename it according to your structure.

Let’s Add the config.ts file under the model. Where we can keep all the configuration-related information and it will be easy to maintain the configuration-related information from one place. I am creating this to put the root/base URL of API which we call in any services or components. Sample config.ts code,

export const ROOT_URL: string = "http://localhost:38223";

JavaScript

We will integrate the Full Node APIs running at localhost: http://localhost:38223.

I have assumed that you have FullNode already. If you don’t have you can download it from here. Open the project and run the Stratis.CirrusMinerD project in devmode. You can use the below command to run FullNode.

cd StratisFullNode\src\Stratis.CirrusMinerD
dotnet run -devmode=miner

Bash

Open http://localhost:38223/swagger/index.html in your browser and you can see a list of APIs.

Integrate Stratis Blockchain APIs in Your Custom Application

Wallet Component

To integrate the wallet, we will create a wallet service and wallet component. Run the below command to generate service and components for the wallet.

ng g service _service/stratisfullnode/wallet
ng g component apicollection/wallet

Bash

In this article, we will implement 3 endpoints from wallet API, however, the implementations of other API(s) will be similar. From the Wallet API Controller, we will call 3 endpoints: Wallet Load, Wallet balance, and WalletSplitcoins.

Endpoint: /api/Wallet/load: Wallet Load is to make sure the private chain is running smoothly and your app is connected with the chain.

Use the below credential for Wallet Load after the complete design.

ParametersValue
Namecirrusdev
Passwordpassword

Endpoint:/api/Wallet/balance: It gives the lists of Wallet addresses, amounts, etc. We need a wallet address having a balance on it to deploy the Smart Contract.

Endpoint: /api/Wallet/splitcoins: It creates the requested amount of equal value and gives the list of addresses with balance. If you get one address having balance and need more addresses, then you can use this to split balance and get more addresses with balance.

To handle API posts and responses easily, it is better to create a model for each of them. Likewise, we will create models for WalletLoad, WalletBalance, and WalletSplitcoins. In order to wallet Load, we have to pass parameters: name and password. Therefore, we will create a model walletload with name and password properties.

Code of walletload.ts model is given below,

export class WalletLoad {
  name: string = "";
  password: string = "";
}

JavaScript

Similarly, we will create a model for Walletbalance. Code of walletbalance.ts model is,

export class WalletBalance {
  walletname: string = "";
  accountname: string = "";
  includebalancebyaddress: boolean=false;
}

JavaScript

As above, we will create a model For WalletCoinSplit. Code for waletsplitcoin.ts is given below,

export class WalletSplitCoin {
  walletName: string = "";
  accountName: string = "";
  walletPassword: string = "";
  totalAmountToSplit: number = 1;
  utxosCount: number = 1;
}

JavaScript

Wallet Service

Now, we will create a service class for wallet API(s) as wallet.services.ts. We will import the Root URL from config and use the base URL to call API endpoints. From the Stratis FullNode swagger page, we can see WalletLoad is post method that needs parameters name and password. Similarly, WalletSplitCoin is also a post, and WalletBalance is a get method with parameters. So, we can write code and pass parameters accordingly.

Here, we will create creating three methods in this services as shown,

Below is the code of wallet.services.ts class for those API endpoints.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { ROOT_URL } from '../../_model/config';
@Injectable({
  providedIn: 'root'
})
export class WalletService {

  constructor(private http: HttpClient) { }

  LoadWallet(login:any) {
    return this.http.post(ROOT_URL + '/api/Wallet/load', login, { observe: 'response' });
  }
  WalletBalance(params:any) {
    return this.http.get(ROOT_URL + '/api/Wallet/balance', { params: params });
  }

  WalletSplitCoins(walletSplitCoin: any) {
    return this.http.post(ROOT_URL + '/api/Wallet/splitcoins', walletSplitCoin);
  }
}

JavaScript

We need HttpClient for the http requests so import HttpClient in-app-module.ts as depicted below, if it is not available there, and face an error with it.

Integrate Stratis Blockchain APIs in Your Custom Application

Wallet Component

Now we will import Wallet Service, all Wallet-related models, and call methods of service in wallet.component.ts and pass parameters using model respectively.

Code of wallet.component.ts

import { Component, OnInit } from '@angular/core';
import { WalletLoad } from '../../_model/walletload';
import { WalletService } from '../../_service/stratisfullnode/wallet.service';
import { WalletBalance } from '../../_model/walletbalance';
import { WalletSplitCoin } from '../../_model/walletsplitcoins';
import { HttpParams } from '@angular/common/http';
import Swal from 'sweetalert2';

@Component({
  selector: 'app-wallet',
  templateUrl: './wallet.component.html',
  styleUrls: ['./wallet.component.scss']
})
export class WalletComponent implements OnInit {
  public login: WalletLoad = new WalletLoad();
  public walletbalance: WalletBalance = new WalletBalance();
  public walletSplitCoin: WalletSplitCoin = new WalletSplitCoin();
  isConnected: boolean = false;
  walletInfos: any;
  walletbalances: any;
  walletSplitedCoins: any;
  constructor( private stratisFullNode: WalletService ) { }

  IncludeBalanceByAddress: any = ['true', 'false']

  ngOnInit(): void {
    this.LoadWallet();
  }
  LoadWallet() {
    this.stratisFullNode.LoadWallet(this.login).subscribe((response: any) => {
      console.log(response);
      if (response.ok) {
        this.isConnected = true;
      //  console.log(response);
        Swal.fire('Successful', 'Full Node Connection successful', 'info');
      } else {
       Swal.fire('Oops...', 'Something went wrong!, Please contact your administrator', 'error');
        //alert('Oops...');
        (error: any) => {
          console.log(error);
        }
      }
    });
  }
  WalletBalance() {
    let params = new HttpParams().set("WalletName", this.walletbalance.walletname).set("AccountName", this.walletbalance.accountname).set("IncludeBalanceByAddress", this.walletbalance.includebalancebyaddress);
    this.stratisFullNode.WalletBalance(params).subscribe((response: any) => {
      if (response.balances) {
        this.walletbalances = response.balances;
        //console.log(data);
        console.log(this.walletbalances);
      } else {
      //  Swal.fire('Oops...', 'Something went wrong!, Please contact your administrator', 'error');
        alert('Opps!!!!');
        (error: any) => {
          console.log(error);
        }
      }
    });
  }
  WalletAplitCoins() {
    this.stratisFullNode.WalletSplitCoins(this.walletSplitCoin).subscribe((response: any) => {
      console.log(response);
      if (response.outputs) {
        this.walletSplitedCoins = response.outputs;
        console.log(this.walletSplitedCoins);
        //  alert('Load Successfully')
      } else {
        alert('Oops...');
        (error: any) => {
          console.log(error);
        }
      }
    });
  }
}

JavaScript

For routing, please refer to the app-routing.module.ts from source code. After addition of each component we can add it to this app-routing.module.ts.

Wallet Component Html

In wallet.component.html, we will design forms to pass parameters as user input. It needs one form and submits button for each endpoint. When it gets the response, we are showing the response results just below the submit button. Here is the complete code for wallet.component.html page.

<section class="content-header">
  <div class="container-fluid">
    <div class="row mb-2">
      <div class="col-sm-6">
        <h1>Stratis FullNode APIs </h1>
      </div>
      <div class="col-sm-6">
        <ol class="breadcrumb float-sm-right">
          <li class="breadcrumb-item"><a routerLink="/admin">Wallet</a></li>
          <li class="breadcrumb-item active">Load Wallet</li>
        </ol>
      </div>
    </div>
  </div><!-- /.container-fluid -->
</section>
<!-- Main content -->
<section class="content">
  <div class="container-fluid">
     <form (ngSubmit)="walletLoadForm.form.valid && LoadWallet()" #walletLoadForm="ngForm">
      <div class="card card-primary card-outline">
        <div class="card-header">
          <h3 class="card-title">Wallet Load</h3>
          <div class="card-tools">
            <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
          </div>
        </div>
        <!-- /.card-header -->
        <div class="card-body">
          <div class="row">
            <div class="col-md-6">
              <div class="form-group">
                <label>Name</label>
                <input type="text" class="form-control" placeholder="Name" [ngClass]="{ 'is-invalid': walletLoadForm.submitted && name.invalid }" [(ngModel)]="login.name" name="name" #name="ngModel" required>
                <div class="text-danger" *ngIf="walletLoadForm.submitted && name.invalid">
                  <p *ngIf="name.errors?.required">Name is required</p>
                </div>
              </div>
            </div>
            <div class="col-md-6">
              <div class="form-group">
                <label>Password</label>
                <input type="text" class="form-control" placeholder="Password" [(ngModel)]="login.password" name="type" #type="ngModel" [ngClass]="{ 'is-invalid': walletLoadForm.submitted && type.invalid }" required>
                <div class="text-danger" *ngIf="walletLoadForm.submitted && type.invalid">
                  <p *ngIf="type.errors?.required">Password is required</p>
                </div>
              </div>
            </div>

            <div class="col-sm-2">
              <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Load Wallet</button>
            </div>
            <!-- /.col -->
            <div class="col-sm-6" *ngIf="isConnected">
              <span class="badge badge-success float-sm-right"> Full Node Connection Successful</span>
            </div>
          </div>
        </div>
        <!-- /.card-body -->
      </div>
    </form>
    <!--Wallet Balance-->
    <form (ngSubmit)="walletBalanceForm.form.valid && WalletBalance()" #walletBalanceForm="ngForm">
      <!-- SELECT2 EXAMPLE -->
      <div class="card card-primary card-outline">
        <div class="card-header">
          <h3 class="card-title">Wallet Balance</h3>
          <div class="card-tools">
            <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
          </div>
        </div>
        <!-- /.card-header -->
        <div class="card-body">
          <div class="row">
            <div class="col-md-4">
              <div class="form-group">
                <label>Wallet Name</label>
                <input type="text" class="form-control" placeholder="Wallet Name" [ngClass]="{ 'is-invalid': walletBalanceForm.submitted && walletname.invalid }" [(ngModel)]="walletbalance.walletname" name="walletname" #walletname="ngModel" required>
                <div class="text-danger" *ngIf="walletBalanceForm.submitted && name.invalid">
                  <p *ngIf="walletname.errors?.required">Wallet Name is required</p>
                </div>
              </div>
            </div>
            <div class="col-md-4">
              <div class="form-group">
                <label>Account Name</label>
                <input type="text" class="form-control" placeholder="Account Name" [(ngModel)]="walletbalance.accountname" name="accountname" #accountname="ngModel" [ngClass]="{ 'is-invalid': walletBalanceForm.submitted && accountname.invalid }" required>
                <div class="text-danger" *ngIf="walletBalanceForm.submitted && accountname.invalid">
                  <p *ngIf="accountname.errors?.required">Account Name is required</p>
                </div>
              </div>
            </div>
            <div class="col-sm-4">
              <label for="includebalancebyaddress">IncludeBalanceByAddress</label>
              <select class="custom-select" [(ngModel)]="walletbalance.includebalancebyaddress" name="includebalancebyaddress">
                <option *ngFor="let includebalance of IncludeBalanceByAddress" [ngValue]="includebalance">{{includebalance}}</option>
              </select>
            </div>
          </div>
          <div>

          </div>
          <div class="row">
            <div class="col-sm-4">
              <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Load Wallet Balance</button>
            </div>
            <!-- /.col -->

          </div>
          <div *ngIf="walletbalances" class="card card-primary">
            <div class="card-body">
              <div class="row">
                <table id="appsettingtable" class="table table-striped table- table-bordered">
                  <thead>
                    <tr>
                      <th>Account Name</th>
                      <th>Path</th>
                      <th>CoinType</th>
                      <th>AmountConfirmed</th>
                      <th>Modified by</th>
                      <th>SpendableAmount </th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr *ngFor="let balance of walletbalances">
                      <td>{{balance.accountName}}</td>
                      <td>{{balance.accountHdPath}}</td>
                      <td>{{balance.coinType}}</td>
                      <td>{{balance.amountConfirmed}}</td>
                      <td>{{balance.amountUnconfirmed}}</td>
                      <td>
                        {{balance.spendableAmount}}
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>
            <!-- /.card-header -->
            <h3 class="card-title">List of Addresses</h3>
            <div *ngFor="let balance of walletbalances">
              <div *ngFor="let add of balance.addresses">
                <span><span class="badge">Address:</span>  {{add.address}}</span>
                <span><span class="badge">IsUsed:</span>  {{add.isUsed}}</span>
                <span><span class="badge">IsChange:</span>  {{add.isChange}}</span>
                <span><span class="badge">Amount Confirmed:</span>  {{add.amountConfirmed}}</span>
                <span><span class="badge">Amount Unconfirmed:</span>  {{add.amountUnconfirmed}}</span>
              </div>

            </div>
          </div>
        </div>
        <!-- /.card-body -->
      </div>

    </form>

    <!--Wallet Split Coins-->
    <form (ngSubmit)="walletSplitCoinForm.form.valid && WalletAplitCoins()" #walletSplitCoinForm="ngForm">
      <!-- SELECT2 EXAMPLE -->
      <div class="card card-primary card-outline">
        <div class="card-header">
          <h3 class="card-title">Wallet Split Coins</h3>
          <div class="card-tools">
            <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
          </div>
        </div>
        <!-- /.card-header -->
        <div class="card-body">
          <div class="row">
            <div class="col-md-4">
              <div class="form-group">
                <label>Wallet Name</label>
                <input type="text" class="form-control" placeholder="Wallet Name" [ngClass]="{ 'is-invalid': walletSplitCoinForm.submitted && walletNameSplitCoin.invalid }" [(ngModel)]="walletSplitCoin.walletName" name="walletName" #walletNameSplitCoin="ngModel" required>
                <div class="text-danger" *ngIf="walletSplitCoinForm.submitted && walletNameSplitCoin.invalid">
                  <p *ngIf="walletNameSplitCoin.errors?.required">Wallet Name is required</p>
                </div>
              </div>
            </div>
            <div class="col-md-4">
              <div class="form-group">
                <label>Account Name</label>
                <input type="text" class="form-control" placeholder="Account Name" [(ngModel)]="walletSplitCoin.accountName" name="accountName" #accountNameSplitCoin="ngModel" [ngClass]="{ 'is-invalid': walletSplitCoinForm.submitted && accountNameSplitCoin.invalid }" required>
                <div class="text-danger" *ngIf="walletSplitCoinForm.submitted && accountNameSplitCoin.invalid">
                  <p *ngIf="accountNameSplitCoin.errors?.required">Account Name is required</p>
                </div>
              </div>
            </div>
            <div class="col-md-4">
              <div class="form-group">
                <label>Wallet Password</label>
                <input type="text" class="form-control" placeholder="Wallet Password" [(ngModel)]="walletSplitCoin.walletPassword" name="walletPassword" #walletpassword="ngModel" [ngClass]="{ 'is-invalid': walletSplitCoinForm.submitted && walletpassword.invalid }" required>
                <div class="text-danger" *ngIf="walletSplitCoinForm.submitted && walletpassword.invalid">
                  <p *ngIf="walletpassword.errors?.required">Wallet Password is required</p>
                </div>
              </div>
            </div>
          </div>
          <div class="row">
            <div class="col-md-4">
              <div class="form-group">
                <label>Amount to Split</label>
                <input type="text" class="form-control" placeholder="No of Aplit" [(ngModel)]="walletSplitCoin.totalAmountToSplit" name="totalAmountToSplit" #totalAmountToSplit="ngModel" [ngClass]="{ 'is-invalid': walletSplitCoinForm.submitted && totalAmountToSplit.invalid }" required>
                <div class="text-danger" *ngIf="walletSplitCoinForm.submitted && totalAmountToSplit.invalid">
                  <p *ngIf="totalAmountToSplit.errors?.required">No of Split is required</p>
                </div>
              </div>
            </div>
            <div class="col-md-4">
              <div class="form-group">
                <label>No of Split</label>
                <input type="text" class="form-control" placeholder="No of Aplit" [(ngModel)]="walletSplitCoin.utxosCount" name="utxosCount" #utxosCount="ngModel" [ngClass]="{ 'is-invalid': walletSplitCoinForm.submitted && utxosCount.invalid }" required>
                <div class="text-danger" *ngIf="walletSplitCoinForm.submitted && utxosCount.invalid">
                  <p *ngIf="utxosCount.errors?.required">No of Split is required</p>
                </div>
              </div>
            </div>
          </div>
          <div class="row">
            <div class="col-sm-4">
              <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Wallet Split Coins</button>
            </div>
            <!-- /.col -->

          </div>
        </div>
        <!-- /.card-body -->
      </div>

      <div *ngIf="walletSplitedCoins" class="card card-primary">
        <!-- /.card-header -->
        <div class="card-body">
          <div class="row">
            <table id="appsettingtable" class="table table-striped table- table-bordered">
              <thead>
                <tr>
                  <th>Address</th>
                  <th>Amount</th>
                </tr>
              </thead>
              <tbody>
                <tr *ngFor="let splitCoin of walletSplitedCoins">
                  <td>{{splitCoin.address}}</td>
                  <td>{{splitCoin.amount}}</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
        <!-- /.card-body -->
        <div class="card-footer bg-gradient-green">
          Stratis Blockchain.
        </div>
      </div>
      <!-- /.card -->
    </form>
  </div>
</section>

Markup

The output of above code of Wallet, Wallet Load.

The output of Wallet Balance,

The output of Wallet Split Coin,

Smart Contract Wallet

Similarly, we will implement two API endpoints from SmartContractWallet: WalletCreate and WalletCall. Endpoint: /api/SmartContractWallet/create is used to deploy the Smart Contract using the Bytecode generated from the Sct tool. If we want to change the state of the contract, API endpoint /api/SmartContractWallet/call can be utilized. You can see business case use of it from the previous article Voting Contract. These endpoints need parameters to pass, So we will create a model for both endpoints.

Create model as SmartContractWalletCreate. Code of smartcontractwalletcreate.ts model is given below,

export class SmartContractWalletCreate {
  walletName: string = "";
  accountName: string = "";
  outpoints: Array<TransactionRequest> = [];
  amount: number = 0;
  password: string = "";
  feeAmount: string = "";
  contractCode: string = "";
  gasPrice: number = 10000;
  gasLimit: number=250000;
  sender: string="";

  parameters:Array<string>=[];
}
export class TransactionRequest {
  index: number = 0;
  transactionId: string = "";
}

JavaScript

Code for smartcontractwalletcall.ts,

export class SmartContractWalletCall {
  walletName: string = "";
  accountName: string = "";
  outpoints: Array<TransactionRequest> = [];
  contractAddress: string = "";
  methodName: string = "";
  amount: number = 0;
  password: string = "";
  feeAmount: string = "";
  gasPrice: number = 10000;
  gasLimit: number = 250000;
  sender: string = "";

  parameters: Array<string> = [];
}
export class TransactionRequest {
  index: number = 0;
  transactionId: string = "";
}

JavaScript

After that, we will create Service and Component for Smart Contract Wallet as shown in angular commands.

ng g service _service/smartcontractwallet --skip-tests
ng g component apicollection/smartcontractwallet --skip-tests

Bash

Code for SmartcontractwalletService: smartcontractwallet.service.ts.

import { Injectable } from '@angular/core';

import { HttpClient } from '@angular/common/http';
import { ROOT_URL } from '../../_model/config';

@Injectable({
  providedIn: 'root'
})
export class SmartcontractwalletService {

  constructor(private http: HttpClient) { }

  SmartContractWalletCreate(smartContractWalletCreate: any) {
    return this.http.post(ROOT_URL + '/api/SmartContractWallet/create', smartContractWalletCreate);
  }

  SmartContractWalletCall(smartContractWalletCall: any) {
    return this.http.post(ROOT_URL + '/api/SmartContractWallet/call', smartContractWalletCall);
  }
}

JavaScript

Similarly, we will import Service and model in component and pass parameters to get responses from API endpoints.

Code for smartcontractwallet.component.ts

import { Component, OnInit } from '@angular/core';
import { SmartContractWalletCreate } from '../../_model/smartcontractwalletcreate';
import { SmartcontractwalletService } from '../../_service/stratisfullnode/smartcontractwallet.service';
import { HttpParams } from '@angular/common/http';
import { SmartContractWalletCall } from '../../_model/smartcontractwalletcall';
@Component({
  selector: 'app-smartcontractwallet',
  templateUrl: './smartcontractwallet.component.html',
  styleUrls: ['./smartcontractwallet.component.scss']
})
export class SmartcontractwalletComponent implements OnInit {

  public smartContractWalletCreate: SmartContractWalletCreate = new SmartContractWalletCreate();
  public smartContractWalletCall: SmartContractWalletCall = new SmartContractWalletCall();
  constructor(private smartcontractwalletService: SmartcontractwalletService) { }
  contractOutputTrnHash: any;
  smartcontractWalletCallOutput: any;
  parameter: string = "";
  testparam: null;
  ngOnInit(): void {

  }
  SmartContractWalletCreate() {
    this.smartContractWalletCreate.outpoints = [];
    this.smartContractWalletCreate.parameters[0] = this.parameter;
    if (this.parameter==="null") {
      this.smartContractWalletCreate.parameters = [];
    }
   this.smartcontractwalletService.SmartContractWalletCreate(this.smartContractWalletCreate).subscribe((response: any) => {
      console.log(response);
      if (response) {
        this.contractOutputTrnHash = response;
        console.log(this.contractOutputTrnHash);
        //  alert('Load Successfully')
      } else {
        // Swal.fire('Oops...', 'Something went wrong!, Please contact your administrator', 'error');
        alert('Oops...');
        (error: any) => {
          console.log(error);
        }
      }
    });
  }


  SmartContractWalletCall() {
    this.smartContractWalletCall.outpoints = [];
    this.smartContractWalletCall.parameters[0] = this.parameter;
    if (this.parameter === "null") {
      this.smartContractWalletCall.parameters = [];
    }
       this.smartcontractwalletService.SmartContractWalletCall(this.smartContractWalletCall).subscribe((response: any) => {
      console.log(response);
      if (response) {
        this.smartcontractWalletCallOutput = response;
        console.log(this.smartcontractWalletCallOutput);
        //  alert('Load Successfully')
      } else {
        // Swal.fire('Oops...', 'Something went wrong!, Please contact your administrator', 'error');
        alert('Oops...');
        (error: any) => {
          console.log(error);
        }
      }
    });
  }
}

JavaScript

HTML page of SmartContractWallet.Component.html page.

<section class="content-header">
  <div class="container-fluid">
    <div class="row mb-2">
      <div class="col-sm-6">
        <h1>Stratis FullNode APIs </h1>
      </div>
      <div class="col-sm-6">
        <ol class="breadcrumb float-sm-right">
          <!--<li class="breadcrumb-item"><a routerLink="/admin">Wallet</a></li>
          <li class="breadcrumb-item active">Load Wallet</li>-->
        </ol>
      </div>
    </div>
  </div><!-- /.container-fluid -->
</section>
<!--SmartContract Wallet Create-->
<form (ngSubmit)="smartContractWalletCreateForm.form.valid && SmartContractWalletCreate()" #smartContractWalletCreateForm="ngForm">
  <!-- SELECT2 EXAMPLE -->
  <div class="card card-primary card-outline">
    <div class="card-header">
      <h3 class="card-title">Smart Contract Wallet Create</h3>
      <div class="card-tools">
        <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
      </div>
    </div>
    <!-- /.card-header -->
    <div class="card-body">
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Wallet Name</label>
            <input type="text" class="form-control" placeholder="Wallet Name" [ngClass]="{ 'is-invalid': smartContractWalletCreateForm.submitted && walletName.invalid }" [(ngModel)]="smartContractWalletCreate.walletName" name="walletName" #walletName="ngModel" required>
            <div class="text-danger" *ngIf="smartContractWalletCreateForm.submitted && walletName.invalid">
              <p *ngIf="walletName.errors?.required">Wallet Name is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Account Name</label>
            <input type="text" class="form-control" placeholder="Account Name" [(ngModel)]="smartContractWalletCreate.accountName" name="accountName" #accountName="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCreateForm.submitted && accountName.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCreateForm.submitted && accountName.invalid">
              <p *ngIf="accountName.errors?.required">Account Name is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Password</label>
            <input type="text" class="form-control" placeholder="Password" [(ngModel)]="smartContractWalletCreate.password" name="password" #password="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCreateForm.submitted && password.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCreateForm.submitted && password.invalid">
              <p *ngIf="password.errors?.required">Wallet Password is required</p>
            </div>
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Amount</label>
            <input type="text" class="form-control" placeholder="Amount" [(ngModel)]="smartContractWalletCreate.amount" name="amount" #amount="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCreateForm.submitted && amount.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCreateForm.submitted && amount.invalid">
              <p *ngIf="amount.errors?.required">Amount is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Outpoints</label>
            <input type="text" class="form-control" placeholder="Outpoints" [(ngModel)]="smartContractWalletCreate.outpoints" name="outpoints" #outpoints="ngModel">
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Fee Amount</label>
            <input type="text" class="form-control" placeholder="Fee Amount" [(ngModel)]="smartContractWalletCreate.feeAmount" name="feeAmount" #feeAmount="ngModel">
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Contract Code</label>
            <input type="text" class="form-control" placeholder="Contract Code" [(ngModel)]="smartContractWalletCreate.contractCode" name="contractCode" #contractCode="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCreateForm.submitted && contractCode.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCreateForm.submitted && contractCode.invalid">
              <p *ngIf="contractCode.errors?.required">Contract Code is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Gas Price</label>
            <input type="text" class="form-control" placeholder="Gas Price" [(ngModel)]="smartContractWalletCreate.gasPrice" name="gasPrice" #gasPrice="ngModel">

          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Gas Limit</label>
            <input type="text" class="form-control" placeholder="Gas Limit" [(ngModel)]="smartContractWalletCreate.gasLimit" name="gasLimit" #gasLimit="ngModel">
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Sender</label>
            <input type="text" class="form-control" placeholder="Sender" [(ngModel)]="smartContractWalletCreate.sender" name="sender" #sender="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCreateForm.submitted && sender.invalid }" required>
            <!--<div class="text-danger" *ngIf="smartContractWalletCreateForm.submitted && sender.invalid">
              <p *ngIf="sender.errors?.required">Contract Code is required</p>
            </div>-->
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Parameters</label>
            <input type="text" class="form-control" placeholder="Parameters" [(ngModel)]="parameter" name="parameters" #parameters="ngModel">
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-sm-4">
          <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Create Wallet</button>
        </div>
      </div>
      <div *ngIf="contractOutputTrnHash">
        <span>
          <span>Transaction Hash:  </span>  {{contractOutputTrnHash}}
        </span>
      </div>
    </div>
  </div>

</form>

<!--SmartContract Wallet Call-->
<form (ngSubmit)="smartContractWalletCallForm.form.valid && SmartContractWalletCall()" #smartContractWalletCallForm="ngForm">
  <div class="card card-primary card-outline">
    <div class="card-header">
      <h3 class="card-title">Smart Contract Wallet Call</h3>
      <div class="card-tools">
        <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
      </div>
    </div>
    <!-- /.card-header -->
    <div class="card-body">
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Wallet Name</label>
            <input type="text" class="form-control" placeholder="Wallet Name" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && walletName1.invalid }" [(ngModel)]="smartContractWalletCall.walletName" name="walletName1" #walletName1="ngModel" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && walletName1.invalid">
              <p *ngIf="walletName1.errors?.required">Wallet Name is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Account Name</label>
            <input type="text" class="form-control" placeholder="Account Name" [(ngModel)]="smartContractWalletCall.accountName" name="accountName1" #accountName1="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && accountName1.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && accountName1.invalid">
              <p *ngIf="accountName1.errors?.required">Account Name is required</p>
            </div>
          </div>
        </div>

        <div class="col-md-4">
          <div class="form-group">
            <label>Contract Address</label>
            <input type="text" class="form-control" placeholder="Contract Address" [(ngModel)]="smartContractWalletCall.contractAddress" name="contractAddress" #contractAddress="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && contractAddress.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && contractAddress.invalid">
              <p *ngIf="contractAddress.errors?.required">Contract Address is required</p>
            </div>
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Password</label>
            <input type="text" class="form-control" placeholder="Password" [(ngModel)]="smartContractWalletCall.password" name="password1" #password1="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && password1.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && password1.invalid">
              <p *ngIf="password1.errors?.required">Wallet Password is required</p>
            </div>
          </div>
        </div>

        <div class="col-md-4">
          <div class="form-group">
            <label>Amount</label>
            <input type="text" class="form-control" placeholder="Amount" [(ngModel)]="smartContractWalletCall.amount" name="amount" #amount="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && amount.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && amount.invalid">
              <p *ngIf="amount.errors?.required">Amount is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Outpoints</label>
            <input type="text" class="form-control" placeholder="Outpoints" [(ngModel)]="smartContractWalletCall.outpoints" name="outpoints" #outpoints="ngModel">
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Fee Amount</label>
            <input type="text" class="form-control" placeholder="Fee Amount" [(ngModel)]="smartContractWalletCall.feeAmount" name="feeAmount" #feeAmount="ngModel">
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Gas Price</label>
            <input type="text" class="form-control" placeholder="Gas Price" [(ngModel)]="smartContractWalletCall.gasPrice" name="gasPrice" #gasPrice="ngModel">

          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Gas Limit</label>
            <input type="text" class="form-control" placeholder="Gas Limit" [(ngModel)]="smartContractWalletCall.gasLimit" name="gasLimit" #gasLimit="ngModel">
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Sender</label>
            <input type="text" class="form-control" placeholder="Sender" [(ngModel)]="smartContractWalletCall.sender" name="sender1" #sender1="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && sender1.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && sender1.invalid">
              <p *ngIf="sender1.errors?.required">Sender is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Method Name</label>
            <input type="text" class="form-control" placeholder="Method Name" [(ngModel)]="smartContractWalletCall.methodName" name="methodName" #methodName="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && methodName.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && methodName.invalid">
              <p *ngIf="methodName.errors?.required">Method Name is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Parameters</label>
            <input type="text" class="form-control" placeholder="Parameters" [(ngModel)]="parameter" name="parameters" #parameters="ngModel">
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-sm-4">
          <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Wallet Call</button>
        </div>
        <!-- /.col -->
      </div>
      <div *ngIf="smartcontractWalletCallOutput">
        <h3 class="card-title">Response output</h3><br />
        <span><span class="badge">Fee :</span> {{smartcontractWalletCallOutput.fee}}</span><br />
        <span><span class="badge">Hex:</span>  {{smartcontractWalletCallOutput.hex}}</span><br />
        <span><span class="badge">Message:</span> {{smartcontractWalletCallOutput.message}}</span><br />
        <span><span class="badge">Success:</span>  {{smartcontractWalletCallOutput.success}}</span><br />
        <span><span class="Transaction Id">To:</span>  {{smartcontractWalletCallOutput.transactionId}}</span><br />
      </div>
    </div>
    <!-- /.card-body -->
    <div class="card-footer bg-gradient-green">
      Stratis Blockchain.
    </div>
  </div>
</form>

Markup

The output of above Smart Contract Wallet Creates page.

Output UI to interact with Amart Contract Wallet Call (endpoint: /api/SmartContractWallet/call).

Smart Contract Component

From the SmartContract API Controller, we will call endpoint API/SmartContracts/receipt which gives the receipt of the transaction. We have to pass transaction hash to get transaction receipt. It gives transaction receipts including Gas Used, From and To address, Logs, etc. Additionally, we will integrate endpoint /api/SmartContracts/local-call which creates a local call with a contract without a transaction. As we saw in the previous article when to use local call and contract call.

We will create a Model for GetReceipt and Local-Call.

Model code for smartcontractreceipt.ts

export class SmartContractReceipt {
  txHash: string = "";
}

JavaScript

Model code for smartcontractlocalcall.ts class.

export class SmartContractLocalCall {
  contractAddress: string = "";
  methodName: string = "";
  amount: string = "";
  gasPrice: number = 10000;
  gasLimit: number = 250000;
  sender: string = "";
  parameters: Array<string> = [];
}

JavaScript

Generate Component and Service for Smart Contract API Controller.

ng g service _service/smartcontract --skip-tests
ng g component apicollection/smartcontract --skip-tests

Bash

Code of SmartContractService class,

import { Injectable } from '@angular/core';

import { HttpClient } from '@angular/common/http';
import { ROOT_URL } from '../../_model/config';

@Injectable({
  providedIn: 'root'
})
export class SmartcontractService {

  constructor(private http: HttpClient) { }
  SmartContractReceipt(params: any) {
    return this.http.get(ROOT_URL + '/api/SmartContracts/receipt', { params: params });
  }
  SmartContractLocalCall(smartContractLocalCall: any) {
    return this.http.post(ROOT_URL + '/api/SmartContracts/local-call', smartContractLocalCall);
  }
}

JavaScript

Code of smartcontract.component.ts,

import { Component, OnInit } from '@angular/core';

import { SmartContractReceipt } from '../../_model/smartcontractreceipt';
import { SmartContractLocalCall } from '../../_model/smartcontractlocalcall';
import { SmartcontractService } from '../../_service/stratisfullnode/smartcontract.service';
import { HttpParams } from '@angular/common/http';
@Component({
  selector: 'app-smartcontract',
  templateUrl: './smartcontract.component.html',
  styleUrls: ['./smartcontract.component.scss']
})
export class SmartcontractComponent implements OnInit {
  public smartContractReceipt: SmartContractReceipt = new SmartContractReceipt();
  public smartContractLocalCall: SmartContractLocalCall = new SmartContractLocalCall();
  constructor(private smartcontractService: SmartcontractService) { }
  resultGetReceipt: any;
  parameter: string = "";
  localCallResponseOut: any;
  ngOnInit(): void {

  }

  SmartContractReceipt() {
    let params = new HttpParams().set("txHash", this.smartContractReceipt.txHash);
    this.smartcontractService.SmartContractReceipt(params).subscribe((response: any) => {
      if (response) {
        this.resultGetReceipt = response;
        console.log(this.resultGetReceipt);
      } else {
        alert('Opps!!!!');
        (error: any) => {
          console.log(error);
        }
      }
    });
  }

  SmartContractForLocalCall() {
    this.smartContractLocalCall.parameters= [];    this.smartcontractService.SmartContractLocalCall(this.smartContractLocalCall).subscribe((response: any) => {
      console.log(response);
      if (response) {
        this.localCallResponseOut = response;
        console.log(this.localCallResponseOut);
      } else {
        alert('Oops...');
        (error: any) => {
          console.log(error);
        }
      }
    });
  }
}

JavaScript

HTML for smartcontract.component.html,

<section class="content-header">
  <div class="container-fluid">
    <div class="row mb-2">
      <div class="col-sm-6">
        <h1>Stratis FullNode APIs </h1>
      </div>
      <div class="col-sm-6">
        <ol class="breadcrumb float-sm-right">
        </ol>
      </div>
    </div>
  </div><!-- /.container-fluid -->
</section>
<!--Get Receipt-->

<form (ngSubmit)="smartcontractGetReceiptForm.form.valid && SmartContractReceipt()" #smartcontractGetReceiptForm="ngForm">
  <!-- SELECT2 EXAMPLE -->
  <div class="card card-primary card-outline">
    <div class="card-header">
      <h3 class="card-title">Smart Contract Receipt</h3>
      <div class="card-tools">
        <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
      </div>
    </div>
    <!-- /.card-header -->
    <div class="card-body">
      <div class="row">
        <div class="col-md-12">
          <div class="form-group">
            <label>Transaction Hash </label>
            <input type="text" class="form-control" placeholder="Transaction Hash" [ngClass]="{ 'is-invalid': smartcontractGetReceiptForm.submitted && txHash.invalid }" [(ngModel)]="smartContractReceipt.txHash" name="txHash" #txHash="ngModel" required>
            <div class="text-danger" *ngIf="smartcontractGetReceiptForm.submitted && txHash.invalid">
              <p *ngIf="txHash.errors?.required">Transaction Hash is required</p>
            </div>
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-sm-4">
          <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Get Receipt</button>
        </div>
        <!-- /.col -->

      </div>

      <!-- /.card-body -->
      <div *ngIf="resultGetReceipt">
        <h3 class="card-title">Response output</h3><br />
        <span><span class="badge">Transaction Hash:</span> {{resultGetReceipt.transactionHash}}</span><br />
        <span><span class="badge">Block Hash:</span>  {{resultGetReceipt.blockHash}}</span><br />
        <span><span class="badge">PostState:</span> {{resultGetReceipt.postState}}</span><br />
        <span><span class="badge">From:</span>  {{resultGetReceipt.from}}</span><br />
        <span><span class="badge">To:</span>  {{resultGetReceipt.to}}</span><br />
        <span><span class="badge">GasUsed:</span>  {{resultGetReceipt.gasUsed}}</span><br />
        <span><span class="badge">New Contract Address:</span> {{resultGetReceipt.newContractAddress}}</span><br />
        <span><span class="badge">Success:</span>  {{resultGetReceipt.success}}</span><br />
        <span><span class="badge">Return Value:</span> {{resultGetReceipt.returnValue}}</span><br />
        <span><span class="badge">Bloom:</span>  {{resultGetReceipt.bloom}}</span><br />
        <span><span class="badge">Error:</span>  {{resultGetReceipt.error}}</span><br />
        <span><span class="badge">Log:</span>  {{resultGetReceipt.logs}}</span><br />
      </div>
    </div>
  </div>

</form>


<form (ngSubmit)="smartcontractLocalCallForm.form.valid && SmartContractForLocalCall()" #smartcontractLocalCallForm="ngForm">
  <!-- SELECT2 EXAMPLE -->
  <div class="card card-primary card-outline">
    <div class="card-header">
      <h3 class="card-title">Smart Contract Local Call</h3>
      <div class="card-tools">
        <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
      </div>
    </div>
    <!-- /.card-header -->
    <div class="card-body">
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Contract Address </label>
            <input type="text" class="form-control" placeholder="Contract Address" [ngClass]="{ 'is-invalid': smartcontractLocalCallForm.submitted && contractAddress.invalid }" [(ngModel)]="smartContractLocalCall.contractAddress" name="contractAddress" #contractAddress="ngModel" required>
            <div class="text-danger" *ngIf="smartcontractLocalCallForm.submitted && contractAddress.invalid">
              <p *ngIf="contractAddress.errors?.required">Contract Address is required</p>
            </div>
          </div>
        </div>

        <div class="col-md-4">
          <div class="form-group">
            <label>Method Name </label>
            <input type="text" class="form-control" placeholder="Method Name" [ngClass]="{ 'is-invalid': smartcontractLocalCallForm.submitted && methodName.invalid }" [(ngModel)]="smartContractLocalCall.methodName" name="methodName" #methodName="ngModel" required>
            <div class="text-danger" *ngIf="smartcontractLocalCallForm.submitted && methodName.invalid">
              <p *ngIf="methodName.errors?.required">Method Name is required</p>
            </div>
          </div>
        </div>

        <div class="col-md-4">
          <div class="form-group">
            <label>Amount</label>
            <input type="text" class="form-control" placeholder="Amount" [(ngModel)]="smartContractLocalCall.amount" name="amount" #amount="ngModel" [ngClass]="{ 'is-invalid': smartcontractLocalCallForm.submitted && amount.invalid }" required>

          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Gas Price</label>
            <input type="text" class="form-control" placeholder="Gas Price" [(ngModel)]="smartContractLocalCall.gasPrice" name="gasPrice" #gasPrice="ngModel">

          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Gas Limit</label>
            <input type="text" class="form-control" placeholder="Gas Limit" [(ngModel)]="smartContractLocalCall.gasLimit" name="gasLimit" #gasLimit="ngModel">
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Sender</label>
            <input type="text" class="form-control" placeholder="Sender" [(ngModel)]="smartContractLocalCall.sender" name="sender" #sender="ngModel">

          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Parameters</label>
            <input type="text" class="form-control" placeholder="Parameters" [(ngModel)]="parameter" name="parameters" #parameters="ngModel">
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-sm-4">
          <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Make Local Call</button>
        </div>
      </div>

      <!-- /.card-body -->
      <div *ngIf="localCallResponseOut">
        <h3 class="card-title">Response output</h3><br />
        <span><span class="badge">Internal Transfer:</span>  {{localCallResponseOut.internalTransfers}}</span><br />
        <span><span class="badge">GasConsumed Value:</span> {{localCallResponseOut.gasConsumed.value}}</span><br />
        <span><span class="badge">Revert:</span>  {{localCallResponseOut.revert}}</span><br />
        <span><span class="badge">Error Message:</span>  {{localCallResponseOut.errorMessage}}</span><br />
        <span><span class="badge">Return:</span>  {{localCallResponseOut.return}}</span><br />
        <span><span class="badge">Log:</span>  {{localCallResponseOut.logs}}</span><br />
      </div>
    </div>
  </div>
  <div class="card-footer bg-gradient-green">
    Stratis Blockchain.
  </div>
  <!-- /.card -->
</form>

Markup

Output of Smart Contract Get Receipt UI.

Smart Contract Local call UI.

Summary

Hence, we can integrate Stratis API in any custom application. In this article, we have implemented Stratis private blockchain in our own application through which we can deploy the Smart Contract. Additionally, write-up has shown how can you manage the API get, post and response model as well as segregate services, models for APIs. The article has explained the complete steps to develop components with user interface to validate Startis API with input and response formatted output. Furthermore, you can take idea from this and integrate Stratis Blockchain any API endpoint to your custom application based on your application need. I have developed an angular application for complete demonstration which you can get from repository

Source: https://www.c-sharpcorner.com/article/integrate-stratis-blockchain-apis-in-your-custom-application/

#smartcontract #blockchain 

Integre Las API De Cadena De Bloques De Stratis

En este artículo, aclararé cómo integrar Stratis Blockchain API en aplicaciones personalizadas o de terceros. Crearemos una aplicación angular e integraremos las API privadas de Stratis. Interactuaremos con las API de Stratis Blockchain y mostraremos la respuesta en la aplicación personalizada. Además, este artículo describirá la creación de una interfaz de usuario para implementar el contrato inteligente. Este artículo explica y proporciona el código para todos los puntos finales necesarios para implementar el contrato inteligente; sin embargo, puede obtener ideas e interactuar con otros puntos finales de acuerdo con sus requisitos de software personalizados. Para obtener más detalles sobre cómo escribir un contrato inteligente y generar un código de bytes, puede visitar  aquí .

El código fuente está disponible  aquí .

requisitos previos

  • IDE para Angular (Visual Studio o Visual Studio Code) según usted
  • Nodo completo de Stratis
  • Código de bytes de contrato inteligente

Para este artículo, usaremos angular 12, sin embargo, también será lo mismo para otra versión.

Crear aplicación angular

Crearemos una aplicación angular con CLI angular como se muestra a continuación,

Instale Angular CLI (si no lo tiene).

npm install -g @angular/cli

Intento

Crearemos una nueva aplicación con el siguiente comando,

ng new StratisFullNodeWebApp

JavaScript

Navegaremos hasta la carpeta del proyecto y ejecutaremos la aplicación. Para compilar y ejecutar la aplicación angular, usamos el comando de servicio como se muestra.

cd StratisFullNodeWebApp
ng serve

Intento

Alternativamente, para abrir la aplicación Angular predeterminada: Ejecute el siguiente comando que compila, ejecuta y abre a la vez.

ng serve --open

Intento

El comando –open abre un proyecto en el navegador en  http://localhost:4200/ Para diseñar una interfaz de usuario lucrativa, implementé el tema AdminLTE. Si quieres, también puedes implementarlo siguiendo los pasos desde aquí . 

Crear y agregar modelo en la aplicación Angular

Cree la carpeta _model donde guardaremos todos los modelos para cada componente.

Podemos agregar el modelo usando el comando y también manualmente como se describe a continuación: En la carpeta _model, haga clic con el botón derecho en -> agregar un nuevo elemento -> Agregar archivo mecanografiado y cambiarle el nombre de acuerdo con su estructura.

Agreguemos el archivo config.ts debajo del modelo. Donde podemos mantener toda la información relacionada con la configuración y será fácil mantener la información relacionada con la configuración desde un solo lugar. Estoy creando esto para poner la URL raíz/base de la API a la que llamamos en cualquier servicio o componente. Ejemplo de   código config.ts ,

export const ROOT_URL: string = "http://localhost:38223";

JavaScript

Integraremos las API de nodo completo que se ejecutan en localhost:  http://localhost:38223 .

He asumido que ya tienes FullNode. Si no lo tienes puedes descargarlo desde  aquí . Abra el proyecto y ejecute el proyecto Stratis.CirrusMinerD en modo de desarrollo. Puede usar el siguiente comando para ejecutar FullNode.

cd StratisFullNode\src\Stratis.CirrusMinerD
dotnet run -devmode=miner

Intento

Abra http://localhost:38223/swagger/index.html en su navegador y podrá ver una lista de API.

Integre las API de Blockchain de Stratis en su aplicación personalizada

Componente de billetera

Para integrar la billetera, crearemos un servicio de billetera y un componente de billetera. Ejecute el siguiente comando para generar servicios y componentes para la billetera.

ng g service _service/stratisfullnode/wallet
ng g component apicollection/wallet

Intento

En este artículo, implementaremos 3 puntos finales de la API de la billetera; sin embargo, las implementaciones de otras API serán similares. Desde Wallet API Controller, llamaremos a 3 puntos finales: Wallet Load, Wallet saldo y WalletSplitcoins.

Endpoint: /api/Wallet/load : Wallet Load es para asegurarse de que la cadena privada funcione sin problemas y que su aplicación esté conectada con la cadena.

Utilice la siguiente credencial para la carga de la billetera después del diseño completo.

ParámetrosValor
Nombrecirrusdev
Claveclave

Endpoint:/ api/Wallet/balance : Brinda las listas de direcciones de billetera, montos, etc. Necesitamos una dirección de billetera que tenga saldo para implementar el contrato inteligente.

Endpoint: / api/Wallet/splitcoins : Crea la cantidad solicitada de igual valor y da la lista de direcciones con saldo. Si obtiene una dirección con saldo y necesita más direcciones, puede usar esto para dividir el saldo y obtener más direcciones con saldo.

Para manejar fácilmente las publicaciones y respuestas de la API, es mejor crear un modelo para cada una de ellas. Asimismo, crearemos modelos para WalletLoad, WalletBalance y WalletSplitcoins. Para cargar la billetera, tenemos que pasar los parámetros: nombre y contraseña. Por lo tanto, crearemos una cartera modelo con propiedades de nombre y contraseña.

El código del  modelo walletload.ts  se proporciona a continuación,

export class WalletLoad {
  name: string = "";
  password: string = "";
}

JavaScript

Del mismo modo, crearemos un modelo para Walletbalance. El código del  modelo walletbalance.ts  es,

export class WalletBalance {
  walletname: string = "";
  accountname: string = "";
  includebalancebyaddress: boolean=false;
}

JavaScript

Como arriba, crearemos un modelo para WalletCoinSplit. El código para  waletsplitcoin.ts  se proporciona a continuación,

export class WalletSplitCoin {
  walletName: string = "";
  accountName: string = "";
  walletPassword: string = "";
  totalAmountToSplit: number = 1;
  utxosCount: number = 1;
}

JavaScript

Servicio de billetera

Ahora, crearemos una clase de servicio para las API de billetera como  wallet.services.ts . Importaremos la URL raíz desde la configuración y usaremos la URL base para llamar a los puntos finales de la API. Desde la página de swagger de Stratis FullNode, podemos ver que WalletLoad es un método de publicación que necesita parámetros de nombre y contraseña. Del mismo modo, WalletSplitCoin también es una publicación y WalletBalance es un método de obtención con parámetros. Entonces, podemos escribir código y pasar parámetros en consecuencia.

Aquí, crearemos la creación de tres métodos en estos servicios como se muestra,

A continuación se muestra el código de  la clase wallet.services.ts  para esos puntos finales de la API.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { ROOT_URL } from '../../_model/config';
@Injectable({
  providedIn: 'root'
})
export class WalletService {

  constructor(private http: HttpClient) { }

  LoadWallet(login:any) {
    return this.http.post(ROOT_URL + '/api/Wallet/load', login, { observe: 'response' });
  }
  WalletBalance(params:any) {
    return this.http.get(ROOT_URL + '/api/Wallet/balance', { params: params });
  }

  WalletSplitCoins(walletSplitCoin: any) {
    return this.http.post(ROOT_URL + '/api/Wallet/splitcoins', walletSplitCoin);
  }
}

JavaScript

Necesitamos HttpClient para las solicitudes http, así que importe HttpClient in-app -module.ts  como se muestra a continuación, si no está disponible allí, y enfrente un error con él.

Integre las API de Blockchain de Stratis en su aplicación personalizada

Componente de billetera

Ahora importaremos Wallet Service, todos los modelos relacionados con Wallet y llamaremos a métodos de servicio en  wallet.component.ts  y pasaremos parámetros usando el modelo respectivamente.

Código de  wallet.component.ts

import { Component, OnInit } from '@angular/core';
import { WalletLoad } from '../../_model/walletload';
import { WalletService } from '../../_service/stratisfullnode/wallet.service';
import { WalletBalance } from '../../_model/walletbalance';
import { WalletSplitCoin } from '../../_model/walletsplitcoins';
import { HttpParams } from '@angular/common/http';
import Swal from 'sweetalert2';

@Component({
  selector: 'app-wallet',
  templateUrl: './wallet.component.html',
  styleUrls: ['./wallet.component.scss']
})
export class WalletComponent implements OnInit {
  public login: WalletLoad = new WalletLoad();
  public walletbalance: WalletBalance = new WalletBalance();
  public walletSplitCoin: WalletSplitCoin = new WalletSplitCoin();
  isConnected: boolean = false;
  walletInfos: any;
  walletbalances: any;
  walletSplitedCoins: any;
  constructor( private stratisFullNode: WalletService ) { }

  IncludeBalanceByAddress: any = ['true', 'false']

  ngOnInit(): void {
    this.LoadWallet();
  }
  LoadWallet() {
    this.stratisFullNode.LoadWallet(this.login).subscribe((response: any) => {
      console.log(response);
      if (response.ok) {
        this.isConnected = true;
      //  console.log(response);
        Swal.fire('Successful', 'Full Node Connection successful', 'info');
      } else {
       Swal.fire('Oops...', 'Something went wrong!, Please contact your administrator', 'error');
        //alert('Oops...');
        (error: any) => {
          console.log(error);
        }
      }
    });
  }
  WalletBalance() {
    let params = new HttpParams().set("WalletName", this.walletbalance.walletname).set("AccountName", this.walletbalance.accountname).set("IncludeBalanceByAddress", this.walletbalance.includebalancebyaddress);
    this.stratisFullNode.WalletBalance(params).subscribe((response: any) => {
      if (response.balances) {
        this.walletbalances = response.balances;
        //console.log(data);
        console.log(this.walletbalances);
      } else {
      //  Swal.fire('Oops...', 'Something went wrong!, Please contact your administrator', 'error');
        alert('Opps!!!!');
        (error: any) => {
          console.log(error);
        }
      }
    });
  }
  WalletAplitCoins() {
    this.stratisFullNode.WalletSplitCoins(this.walletSplitCoin).subscribe((response: any) => {
      console.log(response);
      if (response.outputs) {
        this.walletSplitedCoins = response.outputs;
        console.log(this.walletSplitedCoins);
        //  alert('Load Successfully')
      } else {
        alert('Oops...');
        (error: any) => {
          console.log(error);
        }
      }
    });
  }
}

JavaScript

Para el enrutamiento, consulte  app-routing.module.ts del código fuente. Después de agregar cada componente, podemos agregarlo a esta  app-routing.module.ts .

Componente de monedero Html

En wallet.component.html, diseñaremos formularios para pasar parámetros como entrada del usuario. Necesita un formulario y un botón de envío para cada punto final. Cuando recibe la respuesta, mostramos los resultados de la respuesta justo debajo del botón Enviar. Aquí está el código completo para  la página wallet.component.html  .

<section class="content-header">
  <div class="container-fluid">
    <div class="row mb-2">
      <div class="col-sm-6">
        <h1>Stratis FullNode APIs </h1>
      </div>
      <div class="col-sm-6">
        <ol class="breadcrumb float-sm-right">
          <li class="breadcrumb-item"><a routerLink="/admin">Wallet</a></li>
          <li class="breadcrumb-item active">Load Wallet</li>
        </ol>
      </div>
    </div>
  </div><!-- /.container-fluid -->
</section>
<!-- Main content -->
<section class="content">
  <div class="container-fluid">
     <form (ngSubmit)="walletLoadForm.form.valid && LoadWallet()" #walletLoadForm="ngForm">
      <div class="card card-primary card-outline">
        <div class="card-header">
          <h3 class="card-title">Wallet Load</h3>
          <div class="card-tools">
            <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
          </div>
        </div>
        <!-- /.card-header -->
        <div class="card-body">
          <div class="row">
            <div class="col-md-6">
              <div class="form-group">
                <label>Name</label>
                <input type="text" class="form-control" placeholder="Name" [ngClass]="{ 'is-invalid': walletLoadForm.submitted && name.invalid }" [(ngModel)]="login.name" name="name" #name="ngModel" required>
                <div class="text-danger" *ngIf="walletLoadForm.submitted && name.invalid">
                  <p *ngIf="name.errors?.required">Name is required</p>
                </div>
              </div>
            </div>
            <div class="col-md-6">
              <div class="form-group">
                <label>Password</label>
                <input type="text" class="form-control" placeholder="Password" [(ngModel)]="login.password" name="type" #type="ngModel" [ngClass]="{ 'is-invalid': walletLoadForm.submitted && type.invalid }" required>
                <div class="text-danger" *ngIf="walletLoadForm.submitted && type.invalid">
                  <p *ngIf="type.errors?.required">Password is required</p>
                </div>
              </div>
            </div>

            <div class="col-sm-2">
              <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Load Wallet</button>
            </div>
            <!-- /.col -->
            <div class="col-sm-6" *ngIf="isConnected">
              <span class="badge badge-success float-sm-right"> Full Node Connection Successful</span>
            </div>
          </div>
        </div>
        <!-- /.card-body -->
      </div>
    </form>
    <!--Wallet Balance-->
    <form (ngSubmit)="walletBalanceForm.form.valid && WalletBalance()" #walletBalanceForm="ngForm">
      <!-- SELECT2 EXAMPLE -->
      <div class="card card-primary card-outline">
        <div class="card-header">
          <h3 class="card-title">Wallet Balance</h3>
          <div class="card-tools">
            <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
          </div>
        </div>
        <!-- /.card-header -->
        <div class="card-body">
          <div class="row">
            <div class="col-md-4">
              <div class="form-group">
                <label>Wallet Name</label>
                <input type="text" class="form-control" placeholder="Wallet Name" [ngClass]="{ 'is-invalid': walletBalanceForm.submitted && walletname.invalid }" [(ngModel)]="walletbalance.walletname" name="walletname" #walletname="ngModel" required>
                <div class="text-danger" *ngIf="walletBalanceForm.submitted && name.invalid">
                  <p *ngIf="walletname.errors?.required">Wallet Name is required</p>
                </div>
              </div>
            </div>
            <div class="col-md-4">
              <div class="form-group">
                <label>Account Name</label>
                <input type="text" class="form-control" placeholder="Account Name" [(ngModel)]="walletbalance.accountname" name="accountname" #accountname="ngModel" [ngClass]="{ 'is-invalid': walletBalanceForm.submitted && accountname.invalid }" required>
                <div class="text-danger" *ngIf="walletBalanceForm.submitted && accountname.invalid">
                  <p *ngIf="accountname.errors?.required">Account Name is required</p>
                </div>
              </div>
            </div>
            <div class="col-sm-4">
              <label for="includebalancebyaddress">IncludeBalanceByAddress</label>
              <select class="custom-select" [(ngModel)]="walletbalance.includebalancebyaddress" name="includebalancebyaddress">
                <option *ngFor="let includebalance of IncludeBalanceByAddress" [ngValue]="includebalance">{{includebalance}}</option>
              </select>
            </div>
          </div>
          <div>

          </div>
          <div class="row">
            <div class="col-sm-4">
              <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Load Wallet Balance</button>
            </div>
            <!-- /.col -->

          </div>
          <div *ngIf="walletbalances" class="card card-primary">
            <div class="card-body">
              <div class="row">
                <table id="appsettingtable" class="table table-striped table- table-bordered">
                  <thead>
                    <tr>
                      <th>Account Name</th>
                      <th>Path</th>
                      <th>CoinType</th>
                      <th>AmountConfirmed</th>
                      <th>Modified by</th>
                      <th>SpendableAmount </th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr *ngFor="let balance of walletbalances">
                      <td>{{balance.accountName}}</td>
                      <td>{{balance.accountHdPath}}</td>
                      <td>{{balance.coinType}}</td>
                      <td>{{balance.amountConfirmed}}</td>
                      <td>{{balance.amountUnconfirmed}}</td>
                      <td>
                        {{balance.spendableAmount}}
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>
            <!-- /.card-header -->
            <h3 class="card-title">List of Addresses</h3>
            <div *ngFor="let balance of walletbalances">
              <div *ngFor="let add of balance.addresses">
                <span><span class="badge">Address:</span>  {{add.address}}</span>
                <span><span class="badge">IsUsed:</span>  {{add.isUsed}}</span>
                <span><span class="badge">IsChange:</span>  {{add.isChange}}</span>
                <span><span class="badge">Amount Confirmed:</span>  {{add.amountConfirmed}}</span>
                <span><span class="badge">Amount Unconfirmed:</span>  {{add.amountUnconfirmed}}</span>
              </div>

            </div>
          </div>
        </div>
        <!-- /.card-body -->
      </div>

    </form>

    <!--Wallet Split Coins-->
    <form (ngSubmit)="walletSplitCoinForm.form.valid && WalletAplitCoins()" #walletSplitCoinForm="ngForm">
      <!-- SELECT2 EXAMPLE -->
      <div class="card card-primary card-outline">
        <div class="card-header">
          <h3 class="card-title">Wallet Split Coins</h3>
          <div class="card-tools">
            <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
          </div>
        </div>
        <!-- /.card-header -->
        <div class="card-body">
          <div class="row">
            <div class="col-md-4">
              <div class="form-group">
                <label>Wallet Name</label>
                <input type="text" class="form-control" placeholder="Wallet Name" [ngClass]="{ 'is-invalid': walletSplitCoinForm.submitted && walletNameSplitCoin.invalid }" [(ngModel)]="walletSplitCoin.walletName" name="walletName" #walletNameSplitCoin="ngModel" required>
                <div class="text-danger" *ngIf="walletSplitCoinForm.submitted && walletNameSplitCoin.invalid">
                  <p *ngIf="walletNameSplitCoin.errors?.required">Wallet Name is required</p>
                </div>
              </div>
            </div>
            <div class="col-md-4">
              <div class="form-group">
                <label>Account Name</label>
                <input type="text" class="form-control" placeholder="Account Name" [(ngModel)]="walletSplitCoin.accountName" name="accountName" #accountNameSplitCoin="ngModel" [ngClass]="{ 'is-invalid': walletSplitCoinForm.submitted && accountNameSplitCoin.invalid }" required>
                <div class="text-danger" *ngIf="walletSplitCoinForm.submitted && accountNameSplitCoin.invalid">
                  <p *ngIf="accountNameSplitCoin.errors?.required">Account Name is required</p>
                </div>
              </div>
            </div>
            <div class="col-md-4">
              <div class="form-group">
                <label>Wallet Password</label>
                <input type="text" class="form-control" placeholder="Wallet Password" [(ngModel)]="walletSplitCoin.walletPassword" name="walletPassword" #walletpassword="ngModel" [ngClass]="{ 'is-invalid': walletSplitCoinForm.submitted && walletpassword.invalid }" required>
                <div class="text-danger" *ngIf="walletSplitCoinForm.submitted && walletpassword.invalid">
                  <p *ngIf="walletpassword.errors?.required">Wallet Password is required</p>
                </div>
              </div>
            </div>
          </div>
          <div class="row">
            <div class="col-md-4">
              <div class="form-group">
                <label>Amount to Split</label>
                <input type="text" class="form-control" placeholder="No of Aplit" [(ngModel)]="walletSplitCoin.totalAmountToSplit" name="totalAmountToSplit" #totalAmountToSplit="ngModel" [ngClass]="{ 'is-invalid': walletSplitCoinForm.submitted && totalAmountToSplit.invalid }" required>
                <div class="text-danger" *ngIf="walletSplitCoinForm.submitted && totalAmountToSplit.invalid">
                  <p *ngIf="totalAmountToSplit.errors?.required">No of Split is required</p>
                </div>
              </div>
            </div>
            <div class="col-md-4">
              <div class="form-group">
                <label>No of Split</label>
                <input type="text" class="form-control" placeholder="No of Aplit" [(ngModel)]="walletSplitCoin.utxosCount" name="utxosCount" #utxosCount="ngModel" [ngClass]="{ 'is-invalid': walletSplitCoinForm.submitted && utxosCount.invalid }" required>
                <div class="text-danger" *ngIf="walletSplitCoinForm.submitted && utxosCount.invalid">
                  <p *ngIf="utxosCount.errors?.required">No of Split is required</p>
                </div>
              </div>
            </div>
          </div>
          <div class="row">
            <div class="col-sm-4">
              <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Wallet Split Coins</button>
            </div>
            <!-- /.col -->

          </div>
        </div>
        <!-- /.card-body -->
      </div>

      <div *ngIf="walletSplitedCoins" class="card card-primary">
        <!-- /.card-header -->
        <div class="card-body">
          <div class="row">
            <table id="appsettingtable" class="table table-striped table- table-bordered">
              <thead>
                <tr>
                  <th>Address</th>
                  <th>Amount</th>
                </tr>
              </thead>
              <tbody>
                <tr *ngFor="let splitCoin of walletSplitedCoins">
                  <td>{{splitCoin.address}}</td>
                  <td>{{splitCoin.amount}}</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
        <!-- /.card-body -->
        <div class="card-footer bg-gradient-green">
          Stratis Blockchain.
        </div>
      </div>
      <!-- /.card -->
    </form>
  </div>
</section>

Margen

La salida del código anterior de Wallet, Wallet Load.

La salida del Saldo de Wallet,

La salida de Wallet Split Coin,

Cartera de contrato inteligente

De manera similar, implementaremos dos extremos de API de SmartContractWallet: WalletCreate y WalletCall. Punto final:  /api/SmartContractWallet/create  se usa para implementar el contrato inteligente usando el código de bytes generado desde la herramienta Sct. Si queremos cambiar el estado del contrato,   se puede utilizar el extremo de la API /api/SmartContractWallet/call . Puede ver el caso de uso comercial en el artículo anterior  Contrato de votación . Estos puntos finales necesitan parámetros para pasar, por lo que crearemos un modelo para ambos puntos finales.

Crear modelo como SmartContractWalletCreate. El código del  modelo smartcontractwalletcreate.ts  se proporciona a continuación,

export class SmartContractWalletCreate {
  walletName: string = "";
  accountName: string = "";
  outpoints: Array<TransactionRequest> = [];
  amount: number = 0;
  password: string = "";
  feeAmount: string = "";
  contractCode: string = "";
  gasPrice: number = 10000;
  gasLimit: number=250000;
  sender: string="";

  parameters:Array<string>=[];
}
export class TransactionRequest {
  index: number = 0;
  transactionId: string = "";
}

JavaScript

Código para  smartcontractwalletcall.ts,

export class SmartContractWalletCall {
  walletName: string = "";
  accountName: string = "";
  outpoints: Array<TransactionRequest> = [];
  contractAddress: string = "";
  methodName: string = "";
  amount: number = 0;
  password: string = "";
  feeAmount: string = "";
  gasPrice: number = 10000;
  gasLimit: number = 250000;
  sender: string = "";

  parameters: Array<string> = [];
}
export class TransactionRequest {
  index: number = 0;
  transactionId: string = "";
}

JavaScript

Después de eso, crearemos el Servicio y el Componente para Smart Contract Wallet como se muestra en los comandos angulares.

ng g service _service/smartcontractwallet --skip-tests
ng g component apicollection/smartcontractwallet --skip-tests

Intento

Código para SmartcontractwalletService:  smartcontractwallet.service.ts.

import { Injectable } from '@angular/core';

import { HttpClient } from '@angular/common/http';
import { ROOT_URL } from '../../_model/config';

@Injectable({
  providedIn: 'root'
})
export class SmartcontractwalletService {

  constructor(private http: HttpClient) { }

  SmartContractWalletCreate(smartContractWalletCreate: any) {
    return this.http.post(ROOT_URL + '/api/SmartContractWallet/create', smartContractWalletCreate);
  }

  SmartContractWalletCall(smartContractWalletCall: any) {
    return this.http.post(ROOT_URL + '/api/SmartContractWallet/call', smartContractWalletCall);
  }
}

JavaScript

De manera similar, importaremos el servicio y el modelo en el componente y pasaremos los parámetros para obtener respuestas de los puntos finales de la API.

Código para  smartcontractwallet.component.ts

import { Component, OnInit } from '@angular/core';
import { SmartContractWalletCreate } from '../../_model/smartcontractwalletcreate';
import { SmartcontractwalletService } from '../../_service/stratisfullnode/smartcontractwallet.service';
import { HttpParams } from '@angular/common/http';
import { SmartContractWalletCall } from '../../_model/smartcontractwalletcall';
@Component({
  selector: 'app-smartcontractwallet',
  templateUrl: './smartcontractwallet.component.html',
  styleUrls: ['./smartcontractwallet.component.scss']
})
export class SmartcontractwalletComponent implements OnInit {

  public smartContractWalletCreate: SmartContractWalletCreate = new SmartContractWalletCreate();
  public smartContractWalletCall: SmartContractWalletCall = new SmartContractWalletCall();
  constructor(private smartcontractwalletService: SmartcontractwalletService) { }
  contractOutputTrnHash: any;
  smartcontractWalletCallOutput: any;
  parameter: string = "";
  testparam: null;
  ngOnInit(): void {

  }
  SmartContractWalletCreate() {
    this.smartContractWalletCreate.outpoints = [];
    this.smartContractWalletCreate.parameters[0] = this.parameter;
    if (this.parameter==="null") {
      this.smartContractWalletCreate.parameters = [];
    }
   this.smartcontractwalletService.SmartContractWalletCreate(this.smartContractWalletCreate).subscribe((response: any) => {
      console.log(response);
      if (response) {
        this.contractOutputTrnHash = response;
        console.log(this.contractOutputTrnHash);
        //  alert('Load Successfully')
      } else {
        // Swal.fire('Oops...', 'Something went wrong!, Please contact your administrator', 'error');
        alert('Oops...');
        (error: any) => {
          console.log(error);
        }
      }
    });
  }


  SmartContractWalletCall() {
    this.smartContractWalletCall.outpoints = [];
    this.smartContractWalletCall.parameters[0] = this.parameter;
    if (this.parameter === "null") {
      this.smartContractWalletCall.parameters = [];
    }
       this.smartcontractwalletService.SmartContractWalletCall(this.smartContractWalletCall).subscribe((response: any) => {
      console.log(response);
      if (response) {
        this.smartcontractWalletCallOutput = response;
        console.log(this.smartcontractWalletCallOutput);
        //  alert('Load Successfully')
      } else {
        // Swal.fire('Oops...', 'Something went wrong!, Please contact your administrator', 'error');
        alert('Oops...');
        (error: any) => {
          console.log(error);
        }
      }
    });
  }
}

JavaScript

Página HTML de la página  SmartContractWallet.Component.html  .

<section class="content-header">
  <div class="container-fluid">
    <div class="row mb-2">
      <div class="col-sm-6">
        <h1>Stratis FullNode APIs </h1>
      </div>
      <div class="col-sm-6">
        <ol class="breadcrumb float-sm-right">
          <!--<li class="breadcrumb-item"><a routerLink="/admin">Wallet</a></li>
          <li class="breadcrumb-item active">Load Wallet</li>-->
        </ol>
      </div>
    </div>
  </div><!-- /.container-fluid -->
</section>
<!--SmartContract Wallet Create-->
<form (ngSubmit)="smartContractWalletCreateForm.form.valid && SmartContractWalletCreate()" #smartContractWalletCreateForm="ngForm">
  <!-- SELECT2 EXAMPLE -->
  <div class="card card-primary card-outline">
    <div class="card-header">
      <h3 class="card-title">Smart Contract Wallet Create</h3>
      <div class="card-tools">
        <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
      </div>
    </div>
    <!-- /.card-header -->
    <div class="card-body">
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Wallet Name</label>
            <input type="text" class="form-control" placeholder="Wallet Name" [ngClass]="{ 'is-invalid': smartContractWalletCreateForm.submitted && walletName.invalid }" [(ngModel)]="smartContractWalletCreate.walletName" name="walletName" #walletName="ngModel" required>
            <div class="text-danger" *ngIf="smartContractWalletCreateForm.submitted && walletName.invalid">
              <p *ngIf="walletName.errors?.required">Wallet Name is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Account Name</label>
            <input type="text" class="form-control" placeholder="Account Name" [(ngModel)]="smartContractWalletCreate.accountName" name="accountName" #accountName="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCreateForm.submitted && accountName.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCreateForm.submitted && accountName.invalid">
              <p *ngIf="accountName.errors?.required">Account Name is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Password</label>
            <input type="text" class="form-control" placeholder="Password" [(ngModel)]="smartContractWalletCreate.password" name="password" #password="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCreateForm.submitted && password.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCreateForm.submitted && password.invalid">
              <p *ngIf="password.errors?.required">Wallet Password is required</p>
            </div>
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Amount</label>
            <input type="text" class="form-control" placeholder="Amount" [(ngModel)]="smartContractWalletCreate.amount" name="amount" #amount="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCreateForm.submitted && amount.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCreateForm.submitted && amount.invalid">
              <p *ngIf="amount.errors?.required">Amount is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Outpoints</label>
            <input type="text" class="form-control" placeholder="Outpoints" [(ngModel)]="smartContractWalletCreate.outpoints" name="outpoints" #outpoints="ngModel">
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Fee Amount</label>
            <input type="text" class="form-control" placeholder="Fee Amount" [(ngModel)]="smartContractWalletCreate.feeAmount" name="feeAmount" #feeAmount="ngModel">
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Contract Code</label>
            <input type="text" class="form-control" placeholder="Contract Code" [(ngModel)]="smartContractWalletCreate.contractCode" name="contractCode" #contractCode="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCreateForm.submitted && contractCode.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCreateForm.submitted && contractCode.invalid">
              <p *ngIf="contractCode.errors?.required">Contract Code is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Gas Price</label>
            <input type="text" class="form-control" placeholder="Gas Price" [(ngModel)]="smartContractWalletCreate.gasPrice" name="gasPrice" #gasPrice="ngModel">

          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Gas Limit</label>
            <input type="text" class="form-control" placeholder="Gas Limit" [(ngModel)]="smartContractWalletCreate.gasLimit" name="gasLimit" #gasLimit="ngModel">
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Sender</label>
            <input type="text" class="form-control" placeholder="Sender" [(ngModel)]="smartContractWalletCreate.sender" name="sender" #sender="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCreateForm.submitted && sender.invalid }" required>
            <!--<div class="text-danger" *ngIf="smartContractWalletCreateForm.submitted && sender.invalid">
              <p *ngIf="sender.errors?.required">Contract Code is required</p>
            </div>-->
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Parameters</label>
            <input type="text" class="form-control" placeholder="Parameters" [(ngModel)]="parameter" name="parameters" #parameters="ngModel">
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-sm-4">
          <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Create Wallet</button>
        </div>
      </div>
      <div *ngIf="contractOutputTrnHash">
        <span>
          <span>Transaction Hash:  </span>  {{contractOutputTrnHash}}
        </span>
      </div>
    </div>
  </div>

</form>

<!--SmartContract Wallet Call-->
<form (ngSubmit)="smartContractWalletCallForm.form.valid && SmartContractWalletCall()" #smartContractWalletCallForm="ngForm">
  <div class="card card-primary card-outline">
    <div class="card-header">
      <h3 class="card-title">Smart Contract Wallet Call</h3>
      <div class="card-tools">
        <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
      </div>
    </div>
    <!-- /.card-header -->
    <div class="card-body">
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Wallet Name</label>
            <input type="text" class="form-control" placeholder="Wallet Name" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && walletName1.invalid }" [(ngModel)]="smartContractWalletCall.walletName" name="walletName1" #walletName1="ngModel" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && walletName1.invalid">
              <p *ngIf="walletName1.errors?.required">Wallet Name is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Account Name</label>
            <input type="text" class="form-control" placeholder="Account Name" [(ngModel)]="smartContractWalletCall.accountName" name="accountName1" #accountName1="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && accountName1.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && accountName1.invalid">
              <p *ngIf="accountName1.errors?.required">Account Name is required</p>
            </div>
          </div>
        </div>

        <div class="col-md-4">
          <div class="form-group">
            <label>Contract Address</label>
            <input type="text" class="form-control" placeholder="Contract Address" [(ngModel)]="smartContractWalletCall.contractAddress" name="contractAddress" #contractAddress="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && contractAddress.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && contractAddress.invalid">
              <p *ngIf="contractAddress.errors?.required">Contract Address is required</p>
            </div>
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Password</label>
            <input type="text" class="form-control" placeholder="Password" [(ngModel)]="smartContractWalletCall.password" name="password1" #password1="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && password1.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && password1.invalid">
              <p *ngIf="password1.errors?.required">Wallet Password is required</p>
            </div>
          </div>
        </div>

        <div class="col-md-4">
          <div class="form-group">
            <label>Amount</label>
            <input type="text" class="form-control" placeholder="Amount" [(ngModel)]="smartContractWalletCall.amount" name="amount" #amount="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && amount.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && amount.invalid">
              <p *ngIf="amount.errors?.required">Amount is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Outpoints</label>
            <input type="text" class="form-control" placeholder="Outpoints" [(ngModel)]="smartContractWalletCall.outpoints" name="outpoints" #outpoints="ngModel">
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Fee Amount</label>
            <input type="text" class="form-control" placeholder="Fee Amount" [(ngModel)]="smartContractWalletCall.feeAmount" name="feeAmount" #feeAmount="ngModel">
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Gas Price</label>
            <input type="text" class="form-control" placeholder="Gas Price" [(ngModel)]="smartContractWalletCall.gasPrice" name="gasPrice" #gasPrice="ngModel">

          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Gas Limit</label>
            <input type="text" class="form-control" placeholder="Gas Limit" [(ngModel)]="smartContractWalletCall.gasLimit" name="gasLimit" #gasLimit="ngModel">
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Sender</label>
            <input type="text" class="form-control" placeholder="Sender" [(ngModel)]="smartContractWalletCall.sender" name="sender1" #sender1="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && sender1.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && sender1.invalid">
              <p *ngIf="sender1.errors?.required">Sender is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Method Name</label>
            <input type="text" class="form-control" placeholder="Method Name" [(ngModel)]="smartContractWalletCall.methodName" name="methodName" #methodName="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && methodName.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && methodName.invalid">
              <p *ngIf="methodName.errors?.required">Method Name is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Parameters</label>
            <input type="text" class="form-control" placeholder="Parameters" [(ngModel)]="parameter" name="parameters" #parameters="ngModel">
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-sm-4">
          <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Wallet Call</button>
        </div>
        <!-- /.col -->
      </div>
      <div *ngIf="smartcontractWalletCallOutput">
        <h3 class="card-title">Response output</h3><br />
        <span><span class="badge">Fee :</span> {{smartcontractWalletCallOutput.fee}}</span><br />
        <span><span class="badge">Hex:</span>  {{smartcontractWalletCallOutput.hex}}</span><br />
        <span><span class="badge">Message:</span> {{smartcontractWalletCallOutput.message}}</span><br />
        <span><span class="badge">Success:</span>  {{smartcontractWalletCallOutput.success}}</span><br />
        <span><span class="Transaction Id">To:</span>  {{smartcontractWalletCallOutput.transactionId}}</span><br />
      </div>
    </div>
    <!-- /.card-body -->
    <div class="card-footer bg-gradient-green">
      Stratis Blockchain.
    </div>
  </div>
</form>

Margen

El resultado de la página anterior Smart Contract Wallet Creates.

Interfaz de usuario de salida para interactuar con Amart Contract Wallet Call (punto final: /api/SmartContractWallet/call).

Componente de contrato inteligente

Desde el controlador de la API de SmartContract, llamaremos a la  API/SmartContracts/receipt del punto final  que da el recibo de la transacción. Tenemos que pasar el hash de la transacción para obtener el recibo de la transacción. Brinda recibos de transacciones que incluyen gas usado, direcciones de origen y destino, registros, etc. Además, integraremos el punto final  /api/SmartContracts/local-call,  que crea una llamada local con un contrato sin transacción. Como vimos en el  artículo anterior  cuándo usar llamada local y llamada de contrato.

Crearemos un Modelo para GetReceipt y Local-Call.

Código modelo para  smartcontractreceipt.ts

export class SmartContractReceipt {
  txHash: string = "";
}

JavaScript

Código modelo para la clase smartcontractlocalcall.ts  .

export class SmartContractLocalCall {
  contractAddress: string = "";
  methodName: string = "";
  amount: string = "";
  gasPrice: number = 10000;
  gasLimit: number = 250000;
  sender: string = "";
  parameters: Array<string> = [];
}

JavaScript

Generar componente y servicio para Smart Contract API Controller.

ng g service _service/smartcontract --skip-tests
ng g component apicollection/smartcontract --skip-tests

Intento

Código de  la clase SmartContractService  ,

import { Injectable } from '@angular/core';

import { HttpClient } from '@angular/common/http';
import { ROOT_URL } from '../../_model/config';

@Injectable({
  providedIn: 'root'
})
export class SmartcontractService {

  constructor(private http: HttpClient) { }
  SmartContractReceipt(params: any) {
    return this.http.get(ROOT_URL + '/api/SmartContracts/receipt', { params: params });
  }
  SmartContractLocalCall(smartContractLocalCall: any) {
    return this.http.post(ROOT_URL + '/api/SmartContracts/local-call', smartContractLocalCall);
  }
}

JavaScript

Código de  smartcontract.component.ts,

import { Component, OnInit } from '@angular/core';

import { SmartContractReceipt } from '../../_model/smartcontractreceipt';
import { SmartContractLocalCall } from '../../_model/smartcontractlocalcall';
import { SmartcontractService } from '../../_service/stratisfullnode/smartcontract.service';
import { HttpParams } from '@angular/common/http';
@Component({
  selector: 'app-smartcontract',
  templateUrl: './smartcontract.component.html',
  styleUrls: ['./smartcontract.component.scss']
})
export class SmartcontractComponent implements OnInit {
  public smartContractReceipt: SmartContractReceipt = new SmartContractReceipt();
  public smartContractLocalCall: SmartContractLocalCall = new SmartContractLocalCall();
  constructor(private smartcontractService: SmartcontractService) { }
  resultGetReceipt: any;
  parameter: string = "";
  localCallResponseOut: any;
  ngOnInit(): void {

  }

  SmartContractReceipt() {
    let params = new HttpParams().set("txHash", this.smartContractReceipt.txHash);
    this.smartcontractService.SmartContractReceipt(params).subscribe((response: any) => {
      if (response) {
        this.resultGetReceipt = response;
        console.log(this.resultGetReceipt);
      } else {
        alert('Opps!!!!');
        (error: any) => {
          console.log(error);
        }
      }
    });
  }

  SmartContractForLocalCall() {
    this.smartContractLocalCall.parameters= [];    this.smartcontractService.SmartContractLocalCall(this.smartContractLocalCall).subscribe((response: any) => {
      console.log(response);
      if (response) {
        this.localCallResponseOut = response;
        console.log(this.localCallResponseOut);
      } else {
        alert('Oops...');
        (error: any) => {
          console.log(error);
        }
      }
    });
  }
}

JavaScript

HTML para  contrato inteligente.componente.html,

<section class="content-header">
  <div class="container-fluid">
    <div class="row mb-2">
      <div class="col-sm-6">
        <h1>Stratis FullNode APIs </h1>
      </div>
      <div class="col-sm-6">
        <ol class="breadcrumb float-sm-right">
        </ol>
      </div>
    </div>
  </div><!-- /.container-fluid -->
</section>
<!--Get Receipt-->

<form (ngSubmit)="smartcontractGetReceiptForm.form.valid && SmartContractReceipt()" #smartcontractGetReceiptForm="ngForm">
  <!-- SELECT2 EXAMPLE -->
  <div class="card card-primary card-outline">
    <div class="card-header">
      <h3 class="card-title">Smart Contract Receipt</h3>
      <div class="card-tools">
        <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
      </div>
    </div>
    <!-- /.card-header -->
    <div class="card-body">
      <div class="row">
        <div class="col-md-12">
          <div class="form-group">
            <label>Transaction Hash </label>
            <input type="text" class="form-control" placeholder="Transaction Hash" [ngClass]="{ 'is-invalid': smartcontractGetReceiptForm.submitted && txHash.invalid }" [(ngModel)]="smartContractReceipt.txHash" name="txHash" #txHash="ngModel" required>
            <div class="text-danger" *ngIf="smartcontractGetReceiptForm.submitted && txHash.invalid">
              <p *ngIf="txHash.errors?.required">Transaction Hash is required</p>
            </div>
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-sm-4">
          <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Get Receipt</button>
        </div>
        <!-- /.col -->

      </div>

      <!-- /.card-body -->
      <div *ngIf="resultGetReceipt">
        <h3 class="card-title">Response output</h3><br />
        <span><span class="badge">Transaction Hash:</span> {{resultGetReceipt.transactionHash}}</span><br />
        <span><span class="badge">Block Hash:</span>  {{resultGetReceipt.blockHash}}</span><br />
        <span><span class="badge">PostState:</span> {{resultGetReceipt.postState}}</span><br />
        <span><span class="badge">From:</span>  {{resultGetReceipt.from}}</span><br />
        <span><span class="badge">To:</span>  {{resultGetReceipt.to}}</span><br />
        <span><span class="badge">GasUsed:</span>  {{resultGetReceipt.gasUsed}}</span><br />
        <span><span class="badge">New Contract Address:</span> {{resultGetReceipt.newContractAddress}}</span><br />
        <span><span class="badge">Success:</span>  {{resultGetReceipt.success}}</span><br />
        <span><span class="badge">Return Value:</span> {{resultGetReceipt.returnValue}}</span><br />
        <span><span class="badge">Bloom:</span>  {{resultGetReceipt.bloom}}</span><br />
        <span><span class="badge">Error:</span>  {{resultGetReceipt.error}}</span><br />
        <span><span class="badge">Log:</span>  {{resultGetReceipt.logs}}</span><br />
      </div>
    </div>
  </div>

</form>


<form (ngSubmit)="smartcontractLocalCallForm.form.valid && SmartContractForLocalCall()" #smartcontractLocalCallForm="ngForm">
  <!-- SELECT2 EXAMPLE -->
  <div class="card card-primary card-outline">
    <div class="card-header">
      <h3 class="card-title">Smart Contract Local Call</h3>
      <div class="card-tools">
        <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
      </div>
    </div>
    <!-- /.card-header -->
    <div class="card-body">
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Contract Address </label>
            <input type="text" class="form-control" placeholder="Contract Address" [ngClass]="{ 'is-invalid': smartcontractLocalCallForm.submitted && contractAddress.invalid }" [(ngModel)]="smartContractLocalCall.contractAddress" name="contractAddress" #contractAddress="ngModel" required>
            <div class="text-danger" *ngIf="smartcontractLocalCallForm.submitted && contractAddress.invalid">
              <p *ngIf="contractAddress.errors?.required">Contract Address is required</p>
            </div>
          </div>
        </div>

        <div class="col-md-4">
          <div class="form-group">
            <label>Method Name </label>
            <input type="text" class="form-control" placeholder="Method Name" [ngClass]="{ 'is-invalid': smartcontractLocalCallForm.submitted && methodName.invalid }" [(ngModel)]="smartContractLocalCall.methodName" name="methodName" #methodName="ngModel" required>
            <div class="text-danger" *ngIf="smartcontractLocalCallForm.submitted && methodName.invalid">
              <p *ngIf="methodName.errors?.required">Method Name is required</p>
            </div>
          </div>
        </div>

        <div class="col-md-4">
          <div class="form-group">
            <label>Amount</label>
            <input type="text" class="form-control" placeholder="Amount" [(ngModel)]="smartContractLocalCall.amount" name="amount" #amount="ngModel" [ngClass]="{ 'is-invalid': smartcontractLocalCallForm.submitted && amount.invalid }" required>

          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Gas Price</label>
            <input type="text" class="form-control" placeholder="Gas Price" [(ngModel)]="smartContractLocalCall.gasPrice" name="gasPrice" #gasPrice="ngModel">

          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Gas Limit</label>
            <input type="text" class="form-control" placeholder="Gas Limit" [(ngModel)]="smartContractLocalCall.gasLimit" name="gasLimit" #gasLimit="ngModel">
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Sender</label>
            <input type="text" class="form-control" placeholder="Sender" [(ngModel)]="smartContractLocalCall.sender" name="sender" #sender="ngModel">

          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Parameters</label>
            <input type="text" class="form-control" placeholder="Parameters" [(ngModel)]="parameter" name="parameters" #parameters="ngModel">
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-sm-4">
          <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Make Local Call</button>
        </div>
      </div>

      <!-- /.card-body -->
      <div *ngIf="localCallResponseOut">
        <h3 class="card-title">Response output</h3><br />
        <span><span class="badge">Internal Transfer:</span>  {{localCallResponseOut.internalTransfers}}</span><br />
        <span><span class="badge">GasConsumed Value:</span> {{localCallResponseOut.gasConsumed.value}}</span><br />
        <span><span class="badge">Revert:</span>  {{localCallResponseOut.revert}}</span><br />
        <span><span class="badge">Error Message:</span>  {{localCallResponseOut.errorMessage}}</span><br />
        <span><span class="badge">Return:</span>  {{localCallResponseOut.return}}</span><br />
        <span><span class="badge">Log:</span>  {{localCallResponseOut.logs}}</span><br />
      </div>
    </div>
  </div>
  <div class="card-footer bg-gradient-green">
    Stratis Blockchain.
  </div>
  <!-- /.card -->
</form>

Margen

Salida de la interfaz de usuario de obtención de recibo de contrato inteligente.

Interfaz de usuario de llamada local de contrato inteligente.

Resumen

Por lo tanto, podemos integrar la API de Stratis en cualquier aplicación personalizada. En este artículo, hemos implementado la cadena de bloques privada de Stratis en nuestra propia aplicación a través de la cual podemos implementar el contrato inteligente. Además, el artículo ha demostrado cómo puede administrar el modelo de obtención, publicación y respuesta de API, así como servicios segregados, modelos para API. El artículo ha explicado los pasos completos para desarrollar componentes con interfaz de usuario para validar la API de Startis con entrada y salida con formato de respuesta. Además, puede tomar una idea de esto e integrar Stratis Blockchain en cualquier punto final de la API a su aplicación personalizada según las necesidades de su aplicación. Desarrollé una aplicación angular para una demostración completa que puede obtener del  repositorio

Fuente: https://www.c-sharpcorner.com/article/integrate-stratis-blockchain-apis-in-your-custom-application/ 

#smartcontract #blockchain #stratis

Stratis Blockchain API をカスタムアプリケーションに統合する

この記事では、StratisBlockchainAPIをカスタムまたはサードパーティのアプリケーションに統合する方法を説明します。Angularアプリケーションを作成し、StratisPrivateAPIを統合します。Stratis Blockchain APIと対話し、カスタムアプリケーションで応答を表示します。さらに、この記事では、スマートコントラクトを展開するためのユーザーインターフェイスの作成について説明します。この記事では、スマートコントラクトの展開に必要なすべてのエンドポイントのコードについて説明し、提供しています。ただし、カスタムソフトウェア要件に応じて、アイデアを取得し、他のエンドポイントと対話することができます。スマートコントラクトの記述方法とバイトコードの生成方法の詳細については、こちらをご覧 ください

ソースコードは こちらから入手できます。

前提条件

  • Angular用のIDE(VisualStudioまたはVisualStudio Code)
  • Stratis FullNode
  • スマートコントラクトのバイトコード

この記事では、Angular 12を使用しますが、他のバージョンでも同じです。

Angularアプリケーションを作成する

以下の手順に示すように、AngularCLIを使用してAngularアプリケーションを作成します。

Angular CLIをインストールします(お持ちでない場合)。

npm install -g @angular/cli

バッシュ

次のコマンドで新しいアプリを作成します。

ng new StratisFullNodeWebApp

JavaScript

プロジェクトフォルダに移動して、アプリケーションを実行します。Angularアプリケーションをビルドして実行するには、次のようにserveコマンドを使用します。

cd StratisFullNodeWebAppng serve

バッシュ

または、デフォルトのAngularアプリケーションを開くには:ビルド、実行、およびオープンを一度に実行する以下のコマンドを実行します。

ng serve --open

バッシュ

–openコマンドは、 http:// localhost:4200/にあるブラウザーに対してプロジェクトを開きます 。 収益性の高いUIを設計するために、AdminLTEテーマを実装しました。必要に応じて、ここからの手順に従って実装することもできます。 

Angularアプリでモデルを作成して追加する

各コンポーネントのすべてのモデルを保持する_modelフォルダーを作成します。

コマンドを使用してモデルを追加することも、以下に説明するように手動で追加することもできます。_modelフォルダーで右クリック–>新しいアイテムを追加–> typescriptファイルを追加し、構造に応じて名前を変更します。

モデルの下にconfig.tsファイルを追加しましょう。構成関連のすべての情報を保持でき、構成関連の情報を1か所から簡単に維持できる場所。これは、サービスまたはコンポーネントで呼び出すAPIのルート/ベースURLを配置するために作成しています。サンプル のconfig.ts コード、

export const ROOT_URL: string = "http://localhost:38223";

JavaScript

ローカルホストで実行されているフルノードAPIを統合します:  http:// localhost:38223

私はあなたがすでにFullNodeを持っていると仮定しました。お持ちでない場合は、 こちらからダウンロードできます。プロジェクトを開き、devmodeでStratis.CirrusMinerDプロジェクトを実行します。以下のコマンドを使用して、FullNodeを実行できます。

cd StratisFullNode\src\Stratis.CirrusMinerDdotnet run -devmode=miner

バッシュ

ブラウザでhttp:// localhost:38223 / swagger / index.htmlを開くと、APIのリストが表示されます。

StratisBlockchainAPIをカスタムアプリケーションに統合する

ウォレットコンポーネント

ウォレットを統合するために、ウォレットサービスとウォレットコンポーネントを作成します。以下のコマンドを実行して、ウォレットのサービスとコンポーネントを生成します。

ng g service _service/stratisfullnode/walletng g component apicollection/wallet

バッシュ

この記事では、ウォレットAPIから3つのエンドポイントを実装しますが、他のAPIの実装も同様です。Wallet API Controllerから、Wallet Load、Wallet balance、WalletSplitcoinsの3つのエンドポイントを呼び出します。

エンドポイント:/ api / Wallet / load:Wallet Loadは、プライベートチェーンがスムーズに実行され、アプリがチェーンに接続されていることを確認するためのものです。

完全な設計後のウォレットロードには、以下のクレデンシャルを使用してください。

パラメーター価値
名前cirrusdev
パスワードパスワード

エンドポイント:/ api / Wallet / balance:ウォレットアドレス、金額などのリストを提供します。スマートコントラクトを展開するには、バランスの取れたウォレットアドレスが必要です。

エンドポイント:/ api / Wallet / splitcoins:要求された量の等しい値を作成し、バランスの取れたアドレスのリストを提供します。バランスの取れた1つのアドレスを取得し、より多くのアドレスが必要な場合は、これを使用してバランスを分割し、バランスのとれたより多くのアドレスを取得できます。

APIの投稿と応答を簡単に処理するには、それぞれのモデルを作成することをお勧めします。同様に、WalletLoad、WalletBalance、およびWalletSplitcoinsのモデルを作成します。ロードをウォレット化するには、名前とパスワードのパラメーターを渡す必要があります。したがって、名前とパスワードのプロパティを使用してモデルウォレットロードを作成します。

walletload.tsモデルのコードを  以下に示します。

export class WalletLoad {  name: string = "";  password: string = "";}

JavaScript

同様に、Walletbalanceのモデルを作成します。walletbalance.ts モデルのコード は、

export class WalletBalance {  walletname: string = "";  accountname: string = "";  includebalancebyaddress: boolean=false;}

JavaScript

上記のように、WalletCoinSplitのモデルを作成します。waletsplitcoin.ts のコードを 以下に示します。

export class WalletSplitCoin {  walletName: string = "";  accountName: string = "";  walletPassword: string = "";  totalAmountToSplit: number = 1;  utxosCount: number = 1;}

JavaScript

ウォレットサービス

次に、ウォレットAPIのサービスクラスをwallet.services.tsとして 作成します。configからルートURLをインポートし、ベースURLを使用してAPIエンドポイントを呼び出します。Stratis FullNodeのSwaggerページから、WalletLoadがパラメーター名とパスワードを必要とするpostメソッドであることがわかります。同様に、WalletSplitCoinも投稿であり、WalletBalanceはパラメーターを持つgetメソッドです。したがって、コードを記述し、それに応じてパラメーターを渡すことができます。

ここでは、次のように、このサービスで3つのメソッドを作成して作成します。

以下は、  これらのAPIエンドポイントのwallet.services.tsクラスのコードです。

import { Injectable } from '@angular/core';import { HttpClient } from '@angular/common/http';import { ROOT_URL } from '../../_model/config';@Injectable({  providedIn: 'root'})export class WalletService {  constructor(private http: HttpClient) { }  LoadWallet(login:any) {    return this.http.post(ROOT_URL + '/api/Wallet/load', login, { observe: 'response' });  }  WalletBalance(params:any) {    return this.http.get(ROOT_URL + '/api/Wallet/balance', { params: params });  }  WalletSplitCoins(walletSplitCoin: any) {    return this.http.post(ROOT_URL + '/api/Wallet/splitcoins', walletSplitCoin);  }}

JavaScript

httpリクエストにはHttpClientが必要なので、以下に示すようにHttpClient in-app -module.ts をインポートします(そこで利用できない場合)。エラーが発生します。

StratisBlockchainAPIをカスタムアプリケーションに統合する

ウォレットコンポーネント

次に、Wallet Service、すべてのWallet関連モデルをインポートし、  wallet.component.ts でサービスのメソッドを呼び出し、modelを使用してパラメーターを渡します。

wallet.component.tsのコード 

import { Component, OnInit } from '@angular/core';import { WalletLoad } from '../../_model/walletload';import { WalletService } from '../../_service/stratisfullnode/wallet.service';import { WalletBalance } from '../../_model/walletbalance';import { WalletSplitCoin } from '../../_model/walletsplitcoins';import { HttpParams } from '@angular/common/http';import Swal from 'sweetalert2';@Component({  selector: 'app-wallet',  templateUrl: './wallet.component.html',  styleUrls: ['./wallet.component.scss']})export class WalletComponent implements OnInit {  public login: WalletLoad = new WalletLoad();  public walletbalance: WalletBalance = new WalletBalance();  public walletSplitCoin: WalletSplitCoin = new WalletSplitCoin();  isConnected: boolean = false;  walletInfos: any;  walletbalances: any;  walletSplitedCoins: any;  constructor( private stratisFullNode: WalletService ) { }  IncludeBalanceByAddress: any = ['true', 'false']  ngOnInit(): void {    this.LoadWallet();  }  LoadWallet() {    this.stratisFullNode.LoadWallet(this.login).subscribe((response: any) => {      console.log(response);      if (response.ok) {        this.isConnected = true;      //  console.log(response);        Swal.fire('Successful', 'Full Node Connection successful', 'info');      } else {       Swal.fire('Oops...', 'Something went wrong!, Please contact your administrator', 'error');        //alert('Oops...');        (error: any) => {          console.log(error);        }      }    });  }  WalletBalance() {    let params = new HttpParams().set("WalletName", this.walletbalance.walletname).set("AccountName", this.walletbalance.accountname).set("IncludeBalanceByAddress", this.walletbalance.includebalancebyaddress);    this.stratisFullNode.WalletBalance(params).subscribe((response: any) => {      if (response.balances) {        this.walletbalances = response.balances;        //console.log(data);        console.log(this.walletbalances);      } else {      //  Swal.fire('Oops...', 'Something went wrong!, Please contact your administrator', 'error');        alert('Opps!!!!');        (error: any) => {          console.log(error);        }      }    });  }  WalletAplitCoins() {    this.stratisFullNode.WalletSplitCoins(this.walletSplitCoin).subscribe((response: any) => {      console.log(response);      if (response.outputs) {        this.walletSplitedCoins = response.outputs;        console.log(this.walletSplitedCoins);        //  alert('Load Successfully')      } else {        alert('Oops...');        (error: any) => {          console.log(error);        }      }    });  }}

JavaScript

ルーティングについては、ソースコードのapp-routing.module.tsを参照してください 。各コンポーネントを追加した後、この app-routing.module.tsに追加できます。

ウォレットコンポーネントHTML

wallet.component.htmlでは、ユーザー入力としてパラメーターを渡すフォームを設計します。1つのフォームが必要で、エンドポイントごとにボタンを送信します。応答を受け取ると、送信ボタンのすぐ下に応答結果が表示されます。これがwallet.component.html ページの完全なコードです 。

<section class="content-header">
  <div class="container-fluid">
    <div class="row mb-2">
      <div class="col-sm-6">
        <h1>Stratis FullNode APIs </h1>
      </div>
      <div class="col-sm-6">
        <ol class="breadcrumb float-sm-right">
          <li class="breadcrumb-item"><a routerLink="/admin">Wallet</a></li>
          <li class="breadcrumb-item active">Load Wallet</li>
        </ol>
      </div>
    </div>
  </div><!-- /.container-fluid -->
</section>
<!-- Main content -->
<section class="content">
  <div class="container-fluid">
     <form (ngSubmit)="walletLoadForm.form.valid && LoadWallet()" #walletLoadForm="ngForm">
      <div class="card card-primary card-outline">
        <div class="card-header">
          <h3 class="card-title">Wallet Load</h3>
          <div class="card-tools">
            <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
          </div>
        </div>
        <!-- /.card-header -->
        <div class="card-body">
          <div class="row">
            <div class="col-md-6">
              <div class="form-group">
                <label>Name</label>
                <input type="text" class="form-control" placeholder="Name" [ngClass]="{ 'is-invalid': walletLoadForm.submitted && name.invalid }" [(ngModel)]="login.name" name="name" #name="ngModel" required>
                <div class="text-danger" *ngIf="walletLoadForm.submitted && name.invalid">
                  <p *ngIf="name.errors?.required">Name is required</p>
                </div>
              </div>
            </div>
            <div class="col-md-6">
              <div class="form-group">
                <label>Password</label>
                <input type="text" class="form-control" placeholder="Password" [(ngModel)]="login.password" name="type" #type="ngModel" [ngClass]="{ 'is-invalid': walletLoadForm.submitted && type.invalid }" required>
                <div class="text-danger" *ngIf="walletLoadForm.submitted && type.invalid">
                  <p *ngIf="type.errors?.required">Password is required</p>
                </div>
              </div>
            </div>

            <div class="col-sm-2">
              <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Load Wallet</button>
            </div>
            <!-- /.col -->
            <div class="col-sm-6" *ngIf="isConnected">
              <span class="badge badge-success float-sm-right"> Full Node Connection Successful</span>
            </div>
          </div>
        </div>
        <!-- /.card-body -->
      </div>
    </form>
    <!--Wallet Balance-->
    <form (ngSubmit)="walletBalanceForm.form.valid && WalletBalance()" #walletBalanceForm="ngForm">
      <!-- SELECT2 EXAMPLE -->
      <div class="card card-primary card-outline">
        <div class="card-header">
          <h3 class="card-title">Wallet Balance</h3>
          <div class="card-tools">
            <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
          </div>
        </div>
        <!-- /.card-header -->
        <div class="card-body">
          <div class="row">
            <div class="col-md-4">
              <div class="form-group">
                <label>Wallet Name</label>
                <input type="text" class="form-control" placeholder="Wallet Name" [ngClass]="{ 'is-invalid': walletBalanceForm.submitted && walletname.invalid }" [(ngModel)]="walletbalance.walletname" name="walletname" #walletname="ngModel" required>
                <div class="text-danger" *ngIf="walletBalanceForm.submitted && name.invalid">
                  <p *ngIf="walletname.errors?.required">Wallet Name is required</p>
                </div>
              </div>
            </div>
            <div class="col-md-4">
              <div class="form-group">
                <label>Account Name</label>
                <input type="text" class="form-control" placeholder="Account Name" [(ngModel)]="walletbalance.accountname" name="accountname" #accountname="ngModel" [ngClass]="{ 'is-invalid': walletBalanceForm.submitted && accountname.invalid }" required>
                <div class="text-danger" *ngIf="walletBalanceForm.submitted && accountname.invalid">
                  <p *ngIf="accountname.errors?.required">Account Name is required</p>
                </div>
              </div>
            </div>
            <div class="col-sm-4">
              <label for="includebalancebyaddress">IncludeBalanceByAddress</label>
              <select class="custom-select" [(ngModel)]="walletbalance.includebalancebyaddress" name="includebalancebyaddress">
                <option *ngFor="let includebalance of IncludeBalanceByAddress" [ngValue]="includebalance">{{includebalance}}</option>
              </select>
            </div>
          </div>
          <div>

          </div>
          <div class="row">
            <div class="col-sm-4">
              <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Load Wallet Balance</button>
            </div>
            <!-- /.col -->

          </div>
          <div *ngIf="walletbalances" class="card card-primary">
            <div class="card-body">
              <div class="row">
                <table id="appsettingtable" class="table table-striped table- table-bordered">
                  <thead>
                    <tr>
                      <th>Account Name</th>
                      <th>Path</th>
                      <th>CoinType</th>
                      <th>AmountConfirmed</th>
                      <th>Modified by</th>
                      <th>SpendableAmount </th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr *ngFor="let balance of walletbalances">
                      <td>{{balance.accountName}}</td>
                      <td>{{balance.accountHdPath}}</td>
                      <td>{{balance.coinType}}</td>
                      <td>{{balance.amountConfirmed}}</td>
                      <td>{{balance.amountUnconfirmed}}</td>
                      <td>
                        {{balance.spendableAmount}}
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>
            <!-- /.card-header -->
            <h3 class="card-title">List of Addresses</h3>
            <div *ngFor="let balance of walletbalances">
              <div *ngFor="let add of balance.addresses">
                <span><span class="badge">Address:</span>  {{add.address}}</span>
                <span><span class="badge">IsUsed:</span>  {{add.isUsed}}</span>
                <span><span class="badge">IsChange:</span>  {{add.isChange}}</span>
                <span><span class="badge">Amount Confirmed:</span>  {{add.amountConfirmed}}</span>
                <span><span class="badge">Amount Unconfirmed:</span>  {{add.amountUnconfirmed}}</span>
              </div>

            </div>
          </div>
        </div>
        <!-- /.card-body -->
      </div>

    </form>

    <!--Wallet Split Coins-->
    <form (ngSubmit)="walletSplitCoinForm.form.valid && WalletAplitCoins()" #walletSplitCoinForm="ngForm">
      <!-- SELECT2 EXAMPLE -->
      <div class="card card-primary card-outline">
        <div class="card-header">
          <h3 class="card-title">Wallet Split Coins</h3>
          <div class="card-tools">
            <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
          </div>
        </div>
        <!-- /.card-header -->
        <div class="card-body">
          <div class="row">
            <div class="col-md-4">
              <div class="form-group">
                <label>Wallet Name</label>
                <input type="text" class="form-control" placeholder="Wallet Name" [ngClass]="{ 'is-invalid': walletSplitCoinForm.submitted && walletNameSplitCoin.invalid }" [(ngModel)]="walletSplitCoin.walletName" name="walletName" #walletNameSplitCoin="ngModel" required>
                <div class="text-danger" *ngIf="walletSplitCoinForm.submitted && walletNameSplitCoin.invalid">
                  <p *ngIf="walletNameSplitCoin.errors?.required">Wallet Name is required</p>
                </div>
              </div>
            </div>
            <div class="col-md-4">
              <div class="form-group">
                <label>Account Name</label>
                <input type="text" class="form-control" placeholder="Account Name" [(ngModel)]="walletSplitCoin.accountName" name="accountName" #accountNameSplitCoin="ngModel" [ngClass]="{ 'is-invalid': walletSplitCoinForm.submitted && accountNameSplitCoin.invalid }" required>
                <div class="text-danger" *ngIf="walletSplitCoinForm.submitted && accountNameSplitCoin.invalid">
                  <p *ngIf="accountNameSplitCoin.errors?.required">Account Name is required</p>
                </div>
              </div>
            </div>
            <div class="col-md-4">
              <div class="form-group">
                <label>Wallet Password</label>
                <input type="text" class="form-control" placeholder="Wallet Password" [(ngModel)]="walletSplitCoin.walletPassword" name="walletPassword" #walletpassword="ngModel" [ngClass]="{ 'is-invalid': walletSplitCoinForm.submitted && walletpassword.invalid }" required>
                <div class="text-danger" *ngIf="walletSplitCoinForm.submitted && walletpassword.invalid">
                  <p *ngIf="walletpassword.errors?.required">Wallet Password is required</p>
                </div>
              </div>
            </div>
          </div>
          <div class="row">
            <div class="col-md-4">
              <div class="form-group">
                <label>Amount to Split</label>
                <input type="text" class="form-control" placeholder="No of Aplit" [(ngModel)]="walletSplitCoin.totalAmountToSplit" name="totalAmountToSplit" #totalAmountToSplit="ngModel" [ngClass]="{ 'is-invalid': walletSplitCoinForm.submitted && totalAmountToSplit.invalid }" required>
                <div class="text-danger" *ngIf="walletSplitCoinForm.submitted && totalAmountToSplit.invalid">
                  <p *ngIf="totalAmountToSplit.errors?.required">No of Split is required</p>
                </div>
              </div>
            </div>
            <div class="col-md-4">
              <div class="form-group">
                <label>No of Split</label>
                <input type="text" class="form-control" placeholder="No of Aplit" [(ngModel)]="walletSplitCoin.utxosCount" name="utxosCount" #utxosCount="ngModel" [ngClass]="{ 'is-invalid': walletSplitCoinForm.submitted && utxosCount.invalid }" required>
                <div class="text-danger" *ngIf="walletSplitCoinForm.submitted && utxosCount.invalid">
                  <p *ngIf="utxosCount.errors?.required">No of Split is required</p>
                </div>
              </div>
            </div>
          </div>
          <div class="row">
            <div class="col-sm-4">
              <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Wallet Split Coins</button>
            </div>
            <!-- /.col -->

          </div>
        </div>
        <!-- /.card-body -->
      </div>

      <div *ngIf="walletSplitedCoins" class="card card-primary">
        <!-- /.card-header -->
        <div class="card-body">
          <div class="row">
            <table id="appsettingtable" class="table table-striped table- table-bordered">
              <thead>
                <tr>
                  <th>Address</th>
                  <th>Amount</th>
                </tr>
              </thead>
              <tbody>
                <tr *ngFor="let splitCoin of walletSplitedCoins">
                  <td>{{splitCoin.address}}</td>
                  <td>{{splitCoin.amount}}</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
        <!-- /.card-body -->
        <div class="card-footer bg-gradient-green">
          Stratis Blockchain.
        </div>
      </div>
      <!-- /.card -->
    </form>
  </div>
</section>

マークアップ

上記のWalletのコード、WalletLoadの出力。

ウォレット残高の出力、

ウォレットスプリットコインの出力、

スマートコントラクトウォレット

同様に、SmartContractWalletから2つのAPIエンドポイントWalletCreateとWalletCallを実装します。エンドポイント:  / api / SmartContractWallet / create は、Sctツールから生成されたバイトコードを使用してスマートコントラクトをデプロイするために使用されます。コントラクトの状態を変更する場合は、APIエンドポイント / api / SmartContractWallet/call を利用できます。前回の記事「 投票契約」からビジネスケースの使用法を見ることができます。これらのエンドポイントを渡すにはパラメーターが必要なので、両方のエンドポイントのモデルを作成します。

SmartContractWalletCreateとしてモデルを作成します。smartcontractwalletcreate.tsモデルのコードを  以下に示します。

export class SmartContractWalletCreate {  walletName: string = "";  accountName: string = "";  outpoints: Array<TransactionRequest> = [];  amount: number = 0;  password: string = "";  feeAmount: string = "";  contractCode: string = "";  gasPrice: number = 10000;  gasLimit: number=250000;  sender: string="";  parameters:Array<string>=[];}export class TransactionRequest {  index: number = 0;  transactionId: string = "";}

JavaScript

smartcontractwalletcall.tsのコード 、

export class SmartContractWalletCall {  walletName: string = "";  accountName: string = "";  outpoints: Array<TransactionRequest> = [];  contractAddress: string = "";  methodName: string = "";  amount: number = 0;  password: string = "";  feeAmount: string = "";  gasPrice: number = 10000;  gasLimit: number = 250000;  sender: string = "";  parameters: Array<string> = [];}export class TransactionRequest {  index: number = 0;  transactionId: string = "";}

JavaScript

その後、角度コマンドに示すように、スマートコントラクトウォレットのサービスとコンポーネントを作成します。

ng g service _service/smartcontractwallet --skip-testsng g component apicollection/smartcontractwallet --skip-tests

バッシュ

SmartcontractwalletServiceのコード:  smartcontractwallet.service.ts。

import { Injectable } from '@angular/core';import { HttpClient } from '@angular/common/http';import { ROOT_URL } from '../../_model/config';@Injectable({  providedIn: 'root'})export class SmartcontractwalletService {  constructor(private http: HttpClient) { }  SmartContractWalletCreate(smartContractWalletCreate: any) {    return this.http.post(ROOT_URL + '/api/SmartContractWallet/create', smartContractWalletCreate);  }  SmartContractWalletCall(smartContractWalletCall: any) {    return this.http.post(ROOT_URL + '/api/SmartContractWallet/call', smartContractWalletCall);  }}

JavaScript

同様に、サービスとモデルをコンポーネントにインポートし、パラメーターを渡してAPIエンドポイントから応答を取得します。

smartcontractwallet.component.tsのコード 

import { Component, OnInit } from '@angular/core';import { SmartContractWalletCreate } from '../../_model/smartcontractwalletcreate';import { SmartcontractwalletService } from '../../_service/stratisfullnode/smartcontractwallet.service';import { HttpParams } from '@angular/common/http';import { SmartContractWalletCall } from '../../_model/smartcontractwalletcall';@Component({  selector: 'app-smartcontractwallet',  templateUrl: './smartcontractwallet.component.html',  styleUrls: ['./smartcontractwallet.component.scss']})export class SmartcontractwalletComponent implements OnInit {  public smartContractWalletCreate: SmartContractWalletCreate = new SmartContractWalletCreate();  public smartContractWalletCall: SmartContractWalletCall = new SmartContractWalletCall();  constructor(private smartcontractwalletService: SmartcontractwalletService) { }  contractOutputTrnHash: any;  smartcontractWalletCallOutput: any;  parameter: string = "";  testparam: null;  ngOnInit(): void {  }  SmartContractWalletCreate() {    this.smartContractWalletCreate.outpoints = [];    this.smartContractWalletCreate.parameters[0] = this.parameter;    if (this.parameter==="null") {      this.smartContractWalletCreate.parameters = [];    }   this.smartcontractwalletService.SmartContractWalletCreate(this.smartContractWalletCreate).subscribe((response: any) => {      console.log(response);      if (response) {        this.contractOutputTrnHash = response;        console.log(this.contractOutputTrnHash);        //  alert('Load Successfully')      } else {        // Swal.fire('Oops...', 'Something went wrong!, Please contact your administrator', 'error');        alert('Oops...');        (error: any) => {          console.log(error);        }      }    });  }  SmartContractWalletCall() {    this.smartContractWalletCall.outpoints = [];    this.smartContractWalletCall.parameters[0] = this.parameter;    if (this.parameter === "null") {      this.smartContractWalletCall.parameters = [];    }       this.smartcontractwalletService.SmartContractWalletCall(this.smartContractWalletCall).subscribe((response: any) => {      console.log(response);      if (response) {        this.smartcontractWalletCallOutput = response;        console.log(this.smartcontractWalletCallOutput);        //  alert('Load Successfully')      } else {        // Swal.fire('Oops...', 'Something went wrong!, Please contact your administrator', 'error');        alert('Oops...');        (error: any) => {          console.log(error);        }      }    });  }}

JavaScript

SmartContractWallet.Component.htmlページのHTML  ページ。

<section class="content-header">
  <div class="container-fluid">
    <div class="row mb-2">
      <div class="col-sm-6">
        <h1>Stratis FullNode APIs </h1>
      </div>
      <div class="col-sm-6">
        <ol class="breadcrumb float-sm-right">
          <!--<li class="breadcrumb-item"><a routerLink="/admin">Wallet</a></li>
          <li class="breadcrumb-item active">Load Wallet</li>-->
        </ol>
      </div>
    </div>
  </div><!-- /.container-fluid -->
</section>
<!--SmartContract Wallet Create-->
<form (ngSubmit)="smartContractWalletCreateForm.form.valid && SmartContractWalletCreate()" #smartContractWalletCreateForm="ngForm">
  <!-- SELECT2 EXAMPLE -->
  <div class="card card-primary card-outline">
    <div class="card-header">
      <h3 class="card-title">Smart Contract Wallet Create</h3>
      <div class="card-tools">
        <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
      </div>
    </div>
    <!-- /.card-header -->
    <div class="card-body">
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Wallet Name</label>
            <input type="text" class="form-control" placeholder="Wallet Name" [ngClass]="{ 'is-invalid': smartContractWalletCreateForm.submitted && walletName.invalid }" [(ngModel)]="smartContractWalletCreate.walletName" name="walletName" #walletName="ngModel" required>
            <div class="text-danger" *ngIf="smartContractWalletCreateForm.submitted && walletName.invalid">
              <p *ngIf="walletName.errors?.required">Wallet Name is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Account Name</label>
            <input type="text" class="form-control" placeholder="Account Name" [(ngModel)]="smartContractWalletCreate.accountName" name="accountName" #accountName="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCreateForm.submitted && accountName.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCreateForm.submitted && accountName.invalid">
              <p *ngIf="accountName.errors?.required">Account Name is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Password</label>
            <input type="text" class="form-control" placeholder="Password" [(ngModel)]="smartContractWalletCreate.password" name="password" #password="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCreateForm.submitted && password.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCreateForm.submitted && password.invalid">
              <p *ngIf="password.errors?.required">Wallet Password is required</p>
            </div>
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Amount</label>
            <input type="text" class="form-control" placeholder="Amount" [(ngModel)]="smartContractWalletCreate.amount" name="amount" #amount="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCreateForm.submitted && amount.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCreateForm.submitted && amount.invalid">
              <p *ngIf="amount.errors?.required">Amount is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Outpoints</label>
            <input type="text" class="form-control" placeholder="Outpoints" [(ngModel)]="smartContractWalletCreate.outpoints" name="outpoints" #outpoints="ngModel">
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Fee Amount</label>
            <input type="text" class="form-control" placeholder="Fee Amount" [(ngModel)]="smartContractWalletCreate.feeAmount" name="feeAmount" #feeAmount="ngModel">
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Contract Code</label>
            <input type="text" class="form-control" placeholder="Contract Code" [(ngModel)]="smartContractWalletCreate.contractCode" name="contractCode" #contractCode="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCreateForm.submitted && contractCode.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCreateForm.submitted && contractCode.invalid">
              <p *ngIf="contractCode.errors?.required">Contract Code is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Gas Price</label>
            <input type="text" class="form-control" placeholder="Gas Price" [(ngModel)]="smartContractWalletCreate.gasPrice" name="gasPrice" #gasPrice="ngModel">

          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Gas Limit</label>
            <input type="text" class="form-control" placeholder="Gas Limit" [(ngModel)]="smartContractWalletCreate.gasLimit" name="gasLimit" #gasLimit="ngModel">
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Sender</label>
            <input type="text" class="form-control" placeholder="Sender" [(ngModel)]="smartContractWalletCreate.sender" name="sender" #sender="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCreateForm.submitted && sender.invalid }" required>
            <!--<div class="text-danger" *ngIf="smartContractWalletCreateForm.submitted && sender.invalid">
              <p *ngIf="sender.errors?.required">Contract Code is required</p>
            </div>-->
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Parameters</label>
            <input type="text" class="form-control" placeholder="Parameters" [(ngModel)]="parameter" name="parameters" #parameters="ngModel">
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-sm-4">
          <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Create Wallet</button>
        </div>
      </div>
      <div *ngIf="contractOutputTrnHash">
        <span>
          <span>Transaction Hash:  </span>  {{contractOutputTrnHash}}
        </span>
      </div>
    </div>
  </div>

</form>

<!--SmartContract Wallet Call-->
<form (ngSubmit)="smartContractWalletCallForm.form.valid && SmartContractWalletCall()" #smartContractWalletCallForm="ngForm">
  <div class="card card-primary card-outline">
    <div class="card-header">
      <h3 class="card-title">Smart Contract Wallet Call</h3>
      <div class="card-tools">
        <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
      </div>
    </div>
    <!-- /.card-header -->
    <div class="card-body">
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Wallet Name</label>
            <input type="text" class="form-control" placeholder="Wallet Name" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && walletName1.invalid }" [(ngModel)]="smartContractWalletCall.walletName" name="walletName1" #walletName1="ngModel" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && walletName1.invalid">
              <p *ngIf="walletName1.errors?.required">Wallet Name is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Account Name</label>
            <input type="text" class="form-control" placeholder="Account Name" [(ngModel)]="smartContractWalletCall.accountName" name="accountName1" #accountName1="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && accountName1.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && accountName1.invalid">
              <p *ngIf="accountName1.errors?.required">Account Name is required</p>
            </div>
          </div>
        </div>

        <div class="col-md-4">
          <div class="form-group">
            <label>Contract Address</label>
            <input type="text" class="form-control" placeholder="Contract Address" [(ngModel)]="smartContractWalletCall.contractAddress" name="contractAddress" #contractAddress="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && contractAddress.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && contractAddress.invalid">
              <p *ngIf="contractAddress.errors?.required">Contract Address is required</p>
            </div>
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Password</label>
            <input type="text" class="form-control" placeholder="Password" [(ngModel)]="smartContractWalletCall.password" name="password1" #password1="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && password1.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && password1.invalid">
              <p *ngIf="password1.errors?.required">Wallet Password is required</p>
            </div>
          </div>
        </div>

        <div class="col-md-4">
          <div class="form-group">
            <label>Amount</label>
            <input type="text" class="form-control" placeholder="Amount" [(ngModel)]="smartContractWalletCall.amount" name="amount" #amount="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && amount.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && amount.invalid">
              <p *ngIf="amount.errors?.required">Amount is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Outpoints</label>
            <input type="text" class="form-control" placeholder="Outpoints" [(ngModel)]="smartContractWalletCall.outpoints" name="outpoints" #outpoints="ngModel">
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Fee Amount</label>
            <input type="text" class="form-control" placeholder="Fee Amount" [(ngModel)]="smartContractWalletCall.feeAmount" name="feeAmount" #feeAmount="ngModel">
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Gas Price</label>
            <input type="text" class="form-control" placeholder="Gas Price" [(ngModel)]="smartContractWalletCall.gasPrice" name="gasPrice" #gasPrice="ngModel">

          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Gas Limit</label>
            <input type="text" class="form-control" placeholder="Gas Limit" [(ngModel)]="smartContractWalletCall.gasLimit" name="gasLimit" #gasLimit="ngModel">
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Sender</label>
            <input type="text" class="form-control" placeholder="Sender" [(ngModel)]="smartContractWalletCall.sender" name="sender1" #sender1="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && sender1.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && sender1.invalid">
              <p *ngIf="sender1.errors?.required">Sender is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Method Name</label>
            <input type="text" class="form-control" placeholder="Method Name" [(ngModel)]="smartContractWalletCall.methodName" name="methodName" #methodName="ngModel" [ngClass]="{ 'is-invalid': smartContractWalletCallForm.submitted && methodName.invalid }" required>
            <div class="text-danger" *ngIf="smartContractWalletCallForm.submitted && methodName.invalid">
              <p *ngIf="methodName.errors?.required">Method Name is required</p>
            </div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Parameters</label>
            <input type="text" class="form-control" placeholder="Parameters" [(ngModel)]="parameter" name="parameters" #parameters="ngModel">
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-sm-4">
          <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Wallet Call</button>
        </div>
        <!-- /.col -->
      </div>
      <div *ngIf="smartcontractWalletCallOutput">
        <h3 class="card-title">Response output</h3><br />
        <span><span class="badge">Fee :</span> {{smartcontractWalletCallOutput.fee}}</span><br />
        <span><span class="badge">Hex:</span>  {{smartcontractWalletCallOutput.hex}}</span><br />
        <span><span class="badge">Message:</span> {{smartcontractWalletCallOutput.message}}</span><br />
        <span><span class="badge">Success:</span>  {{smartcontractWalletCallOutput.success}}</span><br />
        <span><span class="Transaction Id">To:</span>  {{smartcontractWalletCallOutput.transactionId}}</span><br />
      </div>
    </div>
    <!-- /.card-body -->
    <div class="card-footer bg-gradient-green">
      Stratis Blockchain.
    </div>
  </div>
</form>

マークアップ

上記のスマートコントラクトウォレット作成ページの出力。

Amart Contract Wallet Call(エンドポイント:/ api / SmartContractWallet / call)と対話するための出力UI。

スマートコントラクトコンポーネント

SmartContract APIコントローラーから、トランザクションのレシートを提供するエンドポイント API / SmartContracts/receipt を呼び出します。トランザクションレシートを取得するには、トランザクションハッシュを渡す必要があります。使用ガス、差出人および宛先アドレス、ログなどを含むトランザクションレシートを提供します。さらに、エンドポイント / api / SmartContracts / local-callを統合 して、トランザクションなしで契約付きのローカルコールを作成します。前回の記事で見たように、  市内通話と契約通話をいつ使用するか。

GetReceiptとLocal-Callのモデルを作成します。

smartcontractreceipt.tsのモデルコード 

export class SmartContractReceipt {  txHash: string = "";}

JavaScript

smartcontractlocalcall.ts クラスのモデルコード。

export class SmartContractLocalCall {  contractAddress: string = "";  methodName: string = "";  amount: string = "";  gasPrice: number = 10000;  gasLimit: number = 250000;  sender: string = "";  parameters: Array<string> = [];}

JavaScript

スマートコントラクトAPIコントローラーのコンポーネントとサービスを生成します。

ng g service _service/smartcontract --skip-testsng g component apicollection/smartcontract --skip-tests

バッシュ

SmartContractService クラスのコード 、

import { Injectable } from '@angular/core';import { HttpClient } from '@angular/common/http';import { ROOT_URL } from '../../_model/config';@Injectable({  providedIn: 'root'})export class SmartcontractService {  constructor(private http: HttpClient) { }  SmartContractReceipt(params: any) {    return this.http.get(ROOT_URL + '/api/SmartContracts/receipt', { params: params });  }  SmartContractLocalCall(smartContractLocalCall: any) {    return this.http.post(ROOT_URL + '/api/SmartContracts/local-call', smartContractLocalCall);  }}

JavaScript

smartcontract.component.tsのコード 、

import { Component, OnInit } from '@angular/core';import { SmartContractReceipt } from '../../_model/smartcontractreceipt';import { SmartContractLocalCall } from '../../_model/smartcontractlocalcall';import { SmartcontractService } from '../../_service/stratisfullnode/smartcontract.service';import { HttpParams } from '@angular/common/http';@Component({  selector: 'app-smartcontract',  templateUrl: './smartcontract.component.html',  styleUrls: ['./smartcontract.component.scss']})export class SmartcontractComponent implements OnInit {  public smartContractReceipt: SmartContractReceipt = new SmartContractReceipt();  public smartContractLocalCall: SmartContractLocalCall = new SmartContractLocalCall();  constructor(private smartcontractService: SmartcontractService) { }  resultGetReceipt: any;  parameter: string = "";  localCallResponseOut: any;  ngOnInit(): void {  }  SmartContractReceipt() {    let params = new HttpParams().set("txHash", this.smartContractReceipt.txHash);    this.smartcontractService.SmartContractReceipt(params).subscribe((response: any) => {      if (response) {        this.resultGetReceipt = response;        console.log(this.resultGetReceipt);      } else {        alert('Opps!!!!');        (error: any) => {          console.log(error);        }      }    });  }  SmartContractForLocalCall() {    this.smartContractLocalCall.parameters= [];    this.smartcontractService.SmartContractLocalCall(this.smartContractLocalCall).subscribe((response: any) => {      console.log(response);      if (response) {        this.localCallResponseOut = response;        console.log(this.localCallResponseOut);      } else {        alert('Oops...');        (error: any) => {          console.log(error);        }      }    });  }}

JavaScript

smartcontract.component.htmlのHTML  、

<section class="content-header">
  <div class="container-fluid">
    <div class="row mb-2">
      <div class="col-sm-6">
        <h1>Stratis FullNode APIs </h1>
      </div>
      <div class="col-sm-6">
        <ol class="breadcrumb float-sm-right">
        </ol>
      </div>
    </div>
  </div><!-- /.container-fluid -->
</section>
<!--Get Receipt-->

<form (ngSubmit)="smartcontractGetReceiptForm.form.valid && SmartContractReceipt()" #smartcontractGetReceiptForm="ngForm">
  <!-- SELECT2 EXAMPLE -->
  <div class="card card-primary card-outline">
    <div class="card-header">
      <h3 class="card-title">Smart Contract Receipt</h3>
      <div class="card-tools">
        <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
      </div>
    </div>
    <!-- /.card-header -->
    <div class="card-body">
      <div class="row">
        <div class="col-md-12">
          <div class="form-group">
            <label>Transaction Hash </label>
            <input type="text" class="form-control" placeholder="Transaction Hash" [ngClass]="{ 'is-invalid': smartcontractGetReceiptForm.submitted && txHash.invalid }" [(ngModel)]="smartContractReceipt.txHash" name="txHash" #txHash="ngModel" required>
            <div class="text-danger" *ngIf="smartcontractGetReceiptForm.submitted && txHash.invalid">
              <p *ngIf="txHash.errors?.required">Transaction Hash is required</p>
            </div>
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-sm-4">
          <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Get Receipt</button>
        </div>
        <!-- /.col -->

      </div>

      <!-- /.card-body -->
      <div *ngIf="resultGetReceipt">
        <h3 class="card-title">Response output</h3><br />
        <span><span class="badge">Transaction Hash:</span> {{resultGetReceipt.transactionHash}}</span><br />
        <span><span class="badge">Block Hash:</span>  {{resultGetReceipt.blockHash}}</span><br />
        <span><span class="badge">PostState:</span> {{resultGetReceipt.postState}}</span><br />
        <span><span class="badge">From:</span>  {{resultGetReceipt.from}}</span><br />
        <span><span class="badge">To:</span>  {{resultGetReceipt.to}}</span><br />
        <span><span class="badge">GasUsed:</span>  {{resultGetReceipt.gasUsed}}</span><br />
        <span><span class="badge">New Contract Address:</span> {{resultGetReceipt.newContractAddress}}</span><br />
        <span><span class="badge">Success:</span>  {{resultGetReceipt.success}}</span><br />
        <span><span class="badge">Return Value:</span> {{resultGetReceipt.returnValue}}</span><br />
        <span><span class="badge">Bloom:</span>  {{resultGetReceipt.bloom}}</span><br />
        <span><span class="badge">Error:</span>  {{resultGetReceipt.error}}</span><br />
        <span><span class="badge">Log:</span>  {{resultGetReceipt.logs}}</span><br />
      </div>
    </div>
  </div>

</form>


<form (ngSubmit)="smartcontractLocalCallForm.form.valid && SmartContractForLocalCall()" #smartcontractLocalCallForm="ngForm">
  <!-- SELECT2 EXAMPLE -->
  <div class="card card-primary card-outline">
    <div class="card-header">
      <h3 class="card-title">Smart Contract Local Call</h3>
      <div class="card-tools">
        <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
      </div>
    </div>
    <!-- /.card-header -->
    <div class="card-body">
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Contract Address </label>
            <input type="text" class="form-control" placeholder="Contract Address" [ngClass]="{ 'is-invalid': smartcontractLocalCallForm.submitted && contractAddress.invalid }" [(ngModel)]="smartContractLocalCall.contractAddress" name="contractAddress" #contractAddress="ngModel" required>
            <div class="text-danger" *ngIf="smartcontractLocalCallForm.submitted && contractAddress.invalid">
              <p *ngIf="contractAddress.errors?.required">Contract Address is required</p>
            </div>
          </div>
        </div>

        <div class="col-md-4">
          <div class="form-group">
            <label>Method Name </label>
            <input type="text" class="form-control" placeholder="Method Name" [ngClass]="{ 'is-invalid': smartcontractLocalCallForm.submitted && methodName.invalid }" [(ngModel)]="smartContractLocalCall.methodName" name="methodName" #methodName="ngModel" required>
            <div class="text-danger" *ngIf="smartcontractLocalCallForm.submitted && methodName.invalid">
              <p *ngIf="methodName.errors?.required">Method Name is required</p>
            </div>
          </div>
        </div>

        <div class="col-md-4">
          <div class="form-group">
            <label>Amount</label>
            <input type="text" class="form-control" placeholder="Amount" [(ngModel)]="smartContractLocalCall.amount" name="amount" #amount="ngModel" [ngClass]="{ 'is-invalid': smartcontractLocalCallForm.submitted && amount.invalid }" required>

          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Gas Price</label>
            <input type="text" class="form-control" placeholder="Gas Price" [(ngModel)]="smartContractLocalCall.gasPrice" name="gasPrice" #gasPrice="ngModel">

          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Gas Limit</label>
            <input type="text" class="form-control" placeholder="Gas Limit" [(ngModel)]="smartContractLocalCall.gasLimit" name="gasLimit" #gasLimit="ngModel">
          </div>
        </div>
        <div class="col-md-4">
          <div class="form-group">
            <label>Sender</label>
            <input type="text" class="form-control" placeholder="Sender" [(ngModel)]="smartContractLocalCall.sender" name="sender" #sender="ngModel">

          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <div class="form-group">
            <label>Parameters</label>
            <input type="text" class="form-control" placeholder="Parameters" [(ngModel)]="parameter" name="parameters" #parameters="ngModel">
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-sm-4">
          <button type="submit" class="btn btn-primary"><i class="fa fa-lock"></i> Make Local Call</button>
        </div>
      </div>

      <!-- /.card-body -->
      <div *ngIf="localCallResponseOut">
        <h3 class="card-title">Response output</h3><br />
        <span><span class="badge">Internal Transfer:</span>  {{localCallResponseOut.internalTransfers}}</span><br />
        <span><span class="badge">GasConsumed Value:</span> {{localCallResponseOut.gasConsumed.value}}</span><br />
        <span><span class="badge">Revert:</span>  {{localCallResponseOut.revert}}</span><br />
        <span><span class="badge">Error Message:</span>  {{localCallResponseOut.errorMessage}}</span><br />
        <span><span class="badge">Return:</span>  {{localCallResponseOut.return}}</span><br />
        <span><span class="badge">Log:</span>  {{localCallResponseOut.logs}}</span><br />
      </div>
    </div>
  </div>
  <div class="card-footer bg-gradient-green">
    Stratis Blockchain.
  </div>
  <!-- /.card -->
</form>

マークアップ

スマートコントラクトの出力レシートUIを取得します。

スマートコントラクト市内通話UI。

概要

したがって、StratisAPIを任意のカスタムアプリケーションに統合できます。この記事では、スマートコントラクトをデプロイできる独自のアプリケーションにStratisプライベートブロックチェーンを実装しました。さらに、記事では、APIの取得、投稿、応答モデルを管理し、サービス、APIのモデルを分離する方法を示しています。この記事では、入力および応答形式の出力を使用してStartisAPIを検証するためのユーザーインターフェイスを備えたコンポーネントを開発するための完全な手順について説明しました。さらに、これからアイデアを得て、アプリケーションのニーズに基づいて、任意のAPIエンドポイントをStratisBlockchainをカスタムアプリケーションに統合できます。リポジトリから取得できる完全なデモンストレーション用のAngularアプリケーションを開発しました 。 

ソース:https ://www.c-sharpcorner.com/article/integrate-stratis-blockchain-apis-in-your-custom-application/ 

#smartcontract #blockchain 

What Is Selenium? | Cross-Browser Testing with Selenium

In this Selenium article, we will learn about What Is Selenium? | Cross-Browser Testing with Selenium. Does Selenium support cross browser testing?. When it comes to an application, there are two kinds of user activity: the kind you can control and the

When it comes to an application, there are two kinds of user activity: the kind you can control and the kind you can’t. Irrespective of these actions, you need to build your application to work for all valid cases. The users’ choice of browsers is something that’s out of your control. You have to make sure that your application works perfectly on all browsers; otherwise, you might lose business. And cross-browser testing is a way to identify issues in your application when accessed from different browsers.

This post will look at what Selenium is and why using Selenium is beneficial for cross-browser testing. Then we’ll look at some Python Selenium examples and see cross-browser testing with Selenium in action. But before that, let’s understand why we need cross-browser testing.

Why Do We Need Cross-Browser Testing?

We don’t write different application code for each browser. Then why do we need to test it on different browsers? Yes, the same code goes to all browsers, but not all browsers process the same way, nor do they use the same rendering engine. For example, Chrome uses WebKit, Firefox uses Gecko, and so on. The job of rendering engines is to visualize the application code. So even if the code is the same, the way it’s processed is different.

If your webpage is of a single HTML file with a couple of simple lines, then you won’t see any difference when it’s displayed on different browsers. But you might see some differences if you have a complex website. For example, the web elements aren’t aligned like they’re supposed to be, or the objects aren’t appearing. This could be because the browser is not rendering your code as expected. Cross-browser testing helps you understand how your application works on different browsers and identify issues, if any. Hence, it’s a part of improving your product.

There are different methods/tools for cross-browser testing. It all started with manual testing, but that’s antiquated now. Now, you can either use web automation frameworks or automated testing tools. In this post, we’ll focus on one such framework—Selenium.

What Is Selenium?

Selenium is an open-source framework built for browser automation. The primary purpose of Selenium is to simulate the actions of users within the application. It helps you create and run test cases on applications. These test results help you identify any bugs in your application that you can fix to improve your application’s quality.

Selenium is among the most popular frameworks for automated testing. Selenium is not just a single software program; it’s a suite. It comes with different options:

  • WebDriver: a collection of language-specific bindings to drive a browser
  • IDE: an add-on that will do a simple record and playback of interactions with the browser
  • Grid: to run the tests against a vast combination of browsers/OSs

When you use Selenium, you can automate the browser, giving you many options and features. And because of its flexibility, you can simulate almost everything that a user can do on the application. But because our focus is on cross-browser testing, let’s see how Selenium is beneficial for it.

Cross-Browser Testing With Selenium

I’m using Selenium WebDriver in these examples, and my choice of programming language is Python. Now we need an application to test how it behaves on different browsers. Not all applications allow you to crawl them or send automated requests. So make sure the application you’re using will enable you to do so. In most cases, you can get this information from the robots.txt file.

Firstly, we need to set up a few things. You need to install Python (2.x or 3.x). Following that, you need to install Selenium for Python. You can do that by running the following command:


pip install selenium

Next, we need to download webdrivers for different browsers. Make sure to download a webdriver that’s compatible with your browser. In this post, I’ll cover the following webdrivers:

  1. Google Chrome (link to download webdriver)
  2. Microsoft Edge (link to download webdriver)
  3. Brave

The script I’ll use will open the website www.testim.io, wait for three seconds, click on the START TESTIM FREE button, wait for three more seconds, and close the browser.

For the clicking on the button part, we need to tell our code how to find the button. We can find an element using different methods, but I’ll do so by using XPath. To find the XPath of an element, right-click on the element and click Inspect.

You should now see the inspection tab with the code for the element highlighted. Right-click on the highlighted section, and under Copy, click Copy XPath.

 

And the XPath will be copied. Now we have all the requirements ready. Let’s see what the Python code looks like.

Cross-Browser Testing With Selenium: Chrome


#Import required libraries
from selenium import webdriver
import time
 
driver = webdriver.Chrome(r'D:\chromedriver') #Mention location of chrome webdriver
 
driver.get("https://www.testim.io/") #Opens website
time.sleep(3)
elem = driver.find_element_by_xpath('//*[@id="main"]/div/div/div/div[2]/a[1]') #Find the button using XPath
elem.click() #Click the button
time.sleep(3)
driver.quit() #Close the browser

While executing any of these codes, you may see an error like this:

You see that there’s a compatibility issue between your browser and the webdriver you’re using. But don’t worry. To get past this, you need to download the compatible webdriver based on the browser version. This is something you’ll have to compromise with when using Selenium web drivers. If you update your browser, you might again have to download another webdriver. If you’re thinking of testing for different versions of a browser, you’d need to have multiple compatible web drivers.

If you don’t want the hassle, you can try different testing methods such as using an AI-powered testing tool like Testim. Testim is an excellent tool and has almost every feature you need to make application testing easy. It’s pretty straightforward to create tests and execute them. You also get many options to customize tests.

Now, let’s come back to Selenium.

Cross-Browser Testing With Selenium: Microsoft Edge


#Import required libraries
from selenium import webdriver
import time
 
driver = webdriver.Chrome(r'D:\msedgedriver') #Mention location of Edge webdriver
 
driver.get("https://www.testim.io/") #Opens website
time.sleep(3)
elem = driver.find_element_by_xpath('//*[@id="main"]/div/div/div/div[2]/a[1]') #Find the button using XPath
elem.click() #Click the button
time.sleep(3)
driver.quit() #Close the browser

The only difference between these two scripts is the webdriver. You have to replace the webdriver for Chrome with the webdriver for Edge.

Cross-Browser Testing With Selenium: Brave

It’s a little different for Brave than the other two browsers. The Brave browser doesn’t have a separate webdriver, but it uses ChromeDriver because Chrome and Brave are built on Chromium. So we need to change some configurations to have Selenium use the Brave browser.

#Import required libraries
from selenium import webdriver
import time
 
options = webdriver.ChromeOptions()
 
 
options.binary_location = 'C:\\Program Files (x86)\\BraveSoftware\\Brave-Browser\\Application\\brave.exe' #
 
driver = webdriver.Chrome(chrome_options= options, executable_path = r'D:\chromedriver') #Mention location of chrome webdriver
 
driver.get("https://www.testim.io/") #Opens website
time.sleep(3)
elem = driver.find_element_by_xpath('//*[@id="main"]/div/div/div/div[2]/a[1]') #Find the button using XPath
elem.click() #Click the button
time.sleep(3)
driver.quit() #Close the browser

What we’re doing is updating the default webdriver configuration and exclusively specifying to use the Brave browser.

You might have observed that we’re not making significant changes to code, just changing the webdriver. The code is reusable for different browsers, and it saves time.

To Conclude

Cross-browser testing is an integral part of application testing. You don’t perform separate tests; instead, you perform the same tests on different browsers. So you need to reduce redundancies in the process. Automated testing is very useful in such cases, and the Selenium framework is a master of this. We’ve gone through different aspects of cross-browser testing with Selenium and some examples of how we can implement it.

As a better alternative, you can use Testim. Testim is an automated testing platform for fast authoring of tests. These are some of the features Testim provides:

  • Record and playback testing
  • Automatic identification and lock-in of elements
  • Reuse of components across tests
  • Customization of tests with code
  • Visual configuration
  • AI-powered stability
  • Root cause analysis

Original article sourced at: https://www.testim.io

#selenium