Duck Hwan

1658750820

Mac OS에 Python을 설치하는 방법

이 기사에서는 Python을 MacOS 장치에 최신 버전으로 설치하고 업데이트하는 방법을 안내합니다.

공식 설치 프로그램에서 Python을 설치하는 것이 macOS에서 가장 안정적인 설치 방법입니다. 여기에는 Python으로 애플리케이션을 개발하는 데 필요한 모든 시스템 종속성이 포함됩니다.

1단계: 공식 설치 프로그램 다운로드

  • python.org, 특히 다운로드 > MacOS 로 이동 하여 최신 설치 파일을 다운로드합니다.
  • machos용 최신 Python 릴리스에서 최신 안정 릴리스의 python 링크를 클릭하십시오. 이 글을 쓰는 현재 사용 가능한 최신 버전의 Python은 v3.10.0입니다.

공식 설치 프로그램 다운로드

  • 이제 버전별 정보를 볼 수 있습니다. 사용 가능한 모든 설치 파일이 있는 테이블이 표시될 때까지 이 페이지에서 아래로 스크롤합니다.

파이썬 설치 프로그램 파일

  • 설명에서 운영 체제에서 macOS로 표시된 파일을 선택합니다. 설치 프로그램 다운로드가 완료되면 마지막으로 다음 단계로 이동합니다.

2단계: 설치 프로그램 실행

  1. 소개를 이해하고 계속을 눌러 다음 단계로 이동합니다.

파이썬 설치 프로그램 실행

2. 중요한 정보를 이해하고 다음 단계로 진행

다음으로 계속

3. 라이선스를 이해하고 계속하기

라이센스를 읽다

4. 계약 및 조건에 동의하면 동의를 선택합니다.

허가를 받아

5. 파일을 설치할 대상을 선택하십시오. 권장 사항은 이 설치 프로그램이 선택한 기본 위치를 변경하지 않는 것입니다.

목적지를 선택

6. 설치가 시작되고 완료되면 이 메시지가 표시됩니다. 이제 Python 3.0이 컴퓨터에 설치되었으므로 이 창을 닫을 수 있습니다.

설치가 시작되었습니다

이제 MacOS 기기에서 Python을 최신 버전으로 설치하고 업데이트할 수 있습니다.

What is GEEK

Buddha Community

Duck Hwan

1658750820

Mac OS에 Python을 설치하는 방법

이 기사에서는 Python을 MacOS 장치에 최신 버전으로 설치하고 업데이트하는 방법을 안내합니다.

공식 설치 프로그램에서 Python을 설치하는 것이 macOS에서 가장 안정적인 설치 방법입니다. 여기에는 Python으로 애플리케이션을 개발하는 데 필요한 모든 시스템 종속성이 포함됩니다.

1단계: 공식 설치 프로그램 다운로드

  • python.org, 특히 다운로드 > MacOS 로 이동 하여 최신 설치 파일을 다운로드합니다.
  • machos용 최신 Python 릴리스에서 최신 안정 릴리스의 python 링크를 클릭하십시오. 이 글을 쓰는 현재 사용 가능한 최신 버전의 Python은 v3.10.0입니다.

공식 설치 프로그램 다운로드

  • 이제 버전별 정보를 볼 수 있습니다. 사용 가능한 모든 설치 파일이 있는 테이블이 표시될 때까지 이 페이지에서 아래로 스크롤합니다.

파이썬 설치 프로그램 파일

  • 설명에서 운영 체제에서 macOS로 표시된 파일을 선택합니다. 설치 프로그램 다운로드가 완료되면 마지막으로 다음 단계로 이동합니다.

2단계: 설치 프로그램 실행

  1. 소개를 이해하고 계속을 눌러 다음 단계로 이동합니다.

파이썬 설치 프로그램 실행

2. 중요한 정보를 이해하고 다음 단계로 진행

다음으로 계속

3. 라이선스를 이해하고 계속하기

라이센스를 읽다

4. 계약 및 조건에 동의하면 동의를 선택합니다.

허가를 받아

5. 파일을 설치할 대상을 선택하십시오. 권장 사항은 이 설치 프로그램이 선택한 기본 위치를 변경하지 않는 것입니다.

목적지를 선택

6. 설치가 시작되고 완료되면 이 메시지가 표시됩니다. 이제 Python 3.0이 컴퓨터에 설치되었으므로 이 창을 닫을 수 있습니다.

설치가 시작되었습니다

이제 MacOS 기기에서 Python을 최신 버전으로 설치하고 업데이트할 수 있습니다.

Cash jons

1614246541

Download MBOX to PST Converter for Mac » Convert MBOX to PST Accurately

Wonderful MBOX to PST transformation expresses that you frequently don’t hear in a similar sentence. Getting an ideal MBOX to PST Converter resembles a slippery dream. Numerous clients are ordinary giving a shot to locate the most ideal approach to accomplish this fantasy. Lamentably, the greater part of the apparatuses that guarantee you to help in accomplishing that fantasy is simply fabrications. They neglect to convey their guarantees, consequently, bringing about a deficient and degenerate Converter measure.

MBOX to PST Conversion with Easy and Accurate

To accomplish this fantasy, you’ll need a transformation arrangement that has the capacity of assuming the difficulties of the advanced email data sets. The transformation arrangement is sponsored by the privileged mechanical progressions. Try not to stress it is a lot more straightforward than it sounds. Also, this article will help you discover one such arrangement. Peruse on and rethink the manner in which you take on your information movement measure.

Mail Extractor Pro: The Tool That’ll Help You Achieve that Dream

The fast advancement in the mechanical world has influenced the interaction of information relocation decidedly. It has Converted the manner in which you approach the way toward moving your information. Outsider programming arrangement appeared because of this very turn of events and is presently the most prescribed answer for convert the Mbox file to pst. Your job is to locate the best outsider converter there is and you are set.

Mail Extractor Pro from MBOX to PST Converter for Mac Software is the best outsider converter apparatus undoubtedly. Suggested by top specialists and easygoing clients the same, the instrument has the correct equilibrium of the relative multitude of fundamental highlights less the intricacy that typically comes free with the apparatus. It is vigorous, exact, precise yet still exceptionally simple to utilize.

Convert Everything including the Unicode Data

What is a transformation interaction that isn’t exact? A fiasco. The fundamental assignment of your converter instrument is to Converter over your information data with exactness and accuracy. You are indeed changing your information starting with one arrangement over then onto the next. Thus, you can’t agree to a transformation arrangement with less exactness.

You can pass judgment on the exactness of any converter device by its capacity to deal with complex Unicode information present in the information documents. Unicode information is perplexing in nature as it is not encoded like your typical text-based information. In this way, it is somewhat difficult to Converter over and numerous converter instruments neglect to manage them.

This converter device causes you to convert everything present in your information document including the Unicode information, giving you an ideal MBOX to PST transformation.

Interface assists a ton with the cycle

The interface is the media of correspondence of any product application. Simpler it is to utilize; simpler it will be for you to make yourself clear to the application.

With this converter device, you get free streaming astutely planned interface. It doesn’t have any perplexing and pointless highlights in plain view that may befuddle you. It just shows the highlights needed to take care of business. It even furnishes you with guidelines to assist you with your Mac MBOX to PST Converter measure.

Download the MBOX to PST converter for Mac free preliminary variant of the device now.

#mbox to pst converter for mac #mac mbox to pst converter #mac mbox to pst #mbox to pst

Neal  Bode

Neal Bode

1598511081

How To Install Golang On Mac Example From Scratch

Install Golang on Mac is very easy. You can download the binary from the official website or install it using homebrew. Golang provides binary distributions for Mac OS X, Windows, and Linux. Then set up your Golang environment. If you are using a different OS, you can download the Go source code and install it from the source.

How To Install Golang On Mac

  1. Download the latest version of Go for your platform here:  https://golang.org/dl/.
  2. Follow the instructions for your platform to install the Go tools:  https://golang.org/doc/install#install. It is recommended to use the default installation settings.
  3. On Mac OS X and Linux, by default Go is installed to directory /usr/local/go, and the GOROOT environment variable is set to /usr/local/go/bin.
  4. You may need to restart any open Terminal sessions for the change to take effect.
  5. Also, we need to install the  VSCode, because there are some tools which we will install inside VSCode which will help us during the developing Go project.

#golang #mac #vscode #go #linux #mac os x

坂本  篤司

坂本 篤司

1651673644

CordaでDAppを作成する方法

2009年1月3日のビットコインの発売により、デジタル資産やデジタル通貨などのトレンドが動き始め、それ以来、イーサリアムやソラナなどのブロックチェーンがさらに作成されています。さまざまな機能とユースケースがありますが、これらのブロックチェーンには1つの共通点があります。それらは、規制当局なしで民主的に運営するように設計されました。したがって、このモデルは、データの機密性を保持し、信頼できる関係者間で共有する必要がある規制対象の業界には適していません。このため、プライベートブロックチェーンが存在します。

プライベートブロックチェーンは、許可されたブロックチェーンです。プライベートブロックチェーンには、ネットワークを制御し、他のノードのアクセス許可とアクセス制御を構成できるネットワークオペレーターと呼ばれるエンティティが含まれています。プライバシーと信頼を維持するために、トランザクションに参加しているエンティティのみがそれについての知識を持ち、他のエンティティはそれにアクセスできません。

プライベートブロックチェーンを利用するデジタルプラットフォームの例としては、Hyperledger Fabric、Ripple、R3のCordaなどがあります。この記事では、Cordaを探索し、CorDappsの作成方法を学びます。始めましょう!

コーダ入門

Cordaは、規制市場でのアプリケーションの開発を容易にする、許可されたピアツーピア(P2P)分散型台帳テクノロジー(DLT)です。Cordaを使用すると、当事者は、ネットワーク参加者の識別に自信を持ちながら、単一のオープンネットワークで相互に自由に発見して取引することができます。

長期的には、Cordaは世界中で共有される分散型台帳を目指しています。そのためには、Cordaソフトウェアを使用する多くのソリューションが、一連の共通の標準と基準に準拠している必要があります。これらの基準のいくつかは、しばしば最終状態の原則として知られ、次のとおりです。

  • 確実なアイデンティティ:当事者は、ネットワークの参加者のアイデンティティに自信を持つことができます。コーダでの身分証明書は、関連当局によって発行された証明書によって表されます
  • プライバシー:取引情報にアクセスできるのは、取引に関与している人と取引元を確認する必要がある人だけです。
  • 相互運用性:Cordaは、多数のアプリケーションが同じネットワーク上で共存および相互運用できるようにすることを目的としています。幅広いプロバイダーからの相互運用性を最適化するために、定義された一連のコントラクトインターフェイスが提供されます

CorDappsの主要コンポーネント

CorDappは、Corda分散アプリケーションの省略形です。CorDappsは、Cordaノードで実行される分散アプリケーションです。以下は、CorDappの主要コンポーネントです。

状態はデータで構成されています。これらはトランザクション間のデータを追跡し、不変です。つまり、形成された後に変更することはできません。代わりに、変更を加えると、新しい継承状態が作成される必要があります。

契約

コントラクトは、トランザクションの入力と出力に適用される検証基準を定義します。コントラクトは、トランザクションの入力状態と出力状態が有効であり、無効なトランザクションが回避されることを保証します。1つ以上のコントラクトがCorDappに存在する場合があり、各コントラクトは1つ以上の状態のルールを提供します。

流れ

フローは、CorDappがネットワーク上で実行する可能性のあるアクティビティであり、CorDappのビジネスロジックを構成します。フローにより、パーティは中央コントローラを使用せずに操作を調整できます。

トランザクション

トランザクションは、元帳の更新要求です。現在の入力状態を消費し、新しい状態を出力して元帳を更新します。トランザクションがノードによって受け入れられる前に、トランザクションは一意で有効であり、適切な関係者によって署名されている必要があります。

公証人

公証人は、ネットワーク資産の重複した支出を防ぐのに役立つCordaネットワークサービスです。これは、各トランザクションに、前のトランザクションで使用されていない一意の入力状態のみが含まれることを保証することによって行われます。公証人も取引の最終性を与えます。公証人が署名した後、取引は完了したと見なされます。

コンセンサス

Cordaでは、有効かつ一意のトランザクションを証明することでコンセンサスを確立できます。コンセンサスは、ノードがネットワークの現在の状態について合意できるようにする方法です。提案された取引を元帳に入力する前に、両当事者はそれが合法であることに同意する必要があります。

Cordaの使用を開始する

Cordaブロックチェーンでのトークンの発行をモデル化するCorDappを作成します。CorDappは、トークンの発行者、所有者、および発行された金額を追跡します。

CorDapp開発に必要なソフトウェアは4つあります。

  • Java 8 JDK
  • IntelliJ IDEA
  • ギット
  • Gradle、5.1から5.6.4までの任意のバージョン

セットアップ

CorDappを設定するには、まず、GitHubリポジトリからCordaJavaテンプレートのクローンを作成します。cordapp-template-java任意のIDEで開きます。IntelliJIDEを使用します。

州を作成する

繰り返しになりますが、状態は不変であり、トランザクション間のデータを追跡します。CorDappには、、、、などの状態に保存する一連の属性がissuerありholderますamount

/contracts/src/main/java/com/template/states次の名前の新しいJavaクラスに移動して作成しますTokenState

package com.template.states

import com.template.contracts.TokenContract;
import net.corda.core.identity.AbstractParty;
import net.corda.core.contracts.BelongsToContract;
import net.corda.core.contracts.ContractState;
import net.corda.core.identity.Party;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;

@BelongsToContract(TokenContract.class)
public class TokenState implements ContractState {
    private Party issuer;
    private Party holder;
    private int amount;

    public TokenState(Party issuer, Party holder, int amount){
        this.issuer = issuer;
        this.holder = holder;
        this.amount = amount;
    }

    public Party getHolder() {
        return holder;
    }

    public Party getIssuer() {
        return issuer;
    }

    public int getAmount() {
        return amount;
    }

    @NotNull
    @Override
    public List<AbstractParty> getParticipants() {
        return Arrays.asList(issuer, holder);
    }
}

上記のコードでは、クラスTokenStateから継承するというクラスを作成しますContractStateContractStateクラスは、状態を実装していることをコーダに伝えます。

@BelongsToContract次に、状態と契約の関係を確立するアノテーションを追加します。これがないと、州はそれを検証するためにどの契約が使用されているかを知りません。このアノテーションを追加すると、まだ作成されていないため、IntelliJでエラーが発生しますTokenContract

次に、、、、の3つの属性を作成issuerholderますamountissuerholder属性はどちらもノード上のエンティティを表すため、タイプが与えられますParty

次に、属性ごとに3つのgetterメソッドを作成します。最後に、getParticipantsどの当事者がトランザクションを認識すべきかを定義するメソッドを作成します。この場合、とだけがトランザクションを認識できるようにしますissuerholder

契約を作成する

繰り返しになりますが、契約は州がどのように進化できるかのルールを定義します。トランザクションが正常に完了する前に、特定の検証を行います。したがって、各州は契約にリンクされています。

/contracts/src/main/java/com/template/contracts次の名前の新しいJavaクラスに移動して作成しますTokenContract

package com.template.contracts

import net.corda.core.contracts.CommandData;
import net.corda.core.contracts.Contract;
import net.corda.core.transactions.LedgerTransaction;

import org.jetbrains.annotations.NotNull;
import com.template.states.TokenState;


public class TokenContract implements Contract {
    public static final String ID = "contracts.TokenContract";

    @Override
    public void verify(@NotNull LedgerTransaction tx) {

        if(tx.getCommands().size() != 1) {
            throw new IllegalArgumentException("expects only one command: ISSUE");
        }
        if(tx.getCommand(0).getValue() instanceof Commands.Issue){
            throw new IllegalArgumentException("issue command expected");
        }
        TokenState state = (TokenState) tx.getOutput(0);
        int amountIssued = state.getAmount();
        if (amountIssued <= 0){
            throw new IllegalArgumentException("amount must be greater than zero");
        }
        if(! (tx.getCommand(0).getSigners().contains(state.getIssuer().getOwningKey()))){
            throw new IllegalArgumentException("transaction must be signed by issuer");
        }
    }
    // Used to indicate the transaction's intent.
    public interface Commands extends CommandData {
        class Issue implements Commands {}
    }
}

上記のコードでは、クラスTokenContractから継承するというクラスを作成しますContract。クラスは、Contract私たちが契約を履行していることをコーダに伝えます。

まず、IDテスト環境でトランザクションを構築するときにコントラクトを識別するという属性を作成します。このID属性は完全にオプションです。

Contract継承したクラスによって与えられたメソッドの1つはverifyメソッドであり、これをオーバーライドする必要があります。このverifyメソッドは、トランザクションを入力として受け取り、定義されたルールに対してそれらを評価します。verifyメソッドが例外をスローしない場合、トランザクションは有効です。

上記のコードを使用して、コントラクトは次のチェックを実行します。

  • トランザクションは発行者が署名する必要があります
  • 金額はゼロより大きくなければなりません
  • コマンドのみissue使用可能
  • 発行であるため、初期入力状態はゼロ

最後に、トークンを別のパーティに発行する予定なので、クラスIssueから継承するというクラスを作成しますCommand。このCommandクラスは、実行されているアクションのタイプを示すために使用されます。

開始フローの記述

繰り返しになりますが、フローにはCorDappのビジネスロジックが含まれています。イニシエーターフローは、トランザクションを開始するノードによって実行されます。これはissuer、この場合です。

workflows/src/main/java/com/template/flows次の名前の新しいJavaクラスに移動して作成しますFlowInitiator

package com.template.flows;

import co.paralleluniverse.fibers.Suspendable;
import com.bootcamp.contracts.TokenContract;
import com.bootcamp.states.TokenState;
import net.corda.core.flows.*;
import net.corda.core.identity.CordaX500Name;
import net.corda.core.identity.Party;
import net.corda.core.transactions.SignedTransaction;
import net.corda.core.transactions.TransactionBuilder;
import net.corda.core.utilities.ProgressTracker;
import net.corda.core.contracts.CommandData;

import static java.util.Collections.singletonList;

    @InitiatingFlow
    @StartableByRPC
    public static class TokenFlowInitiator extends FlowLogic<SignedTransaction> {
        private final Party owner;
        private final int amount;

        public TokenFlowInitiator(Party owner, int amount) {
            this.owner = owner;
            this.amount = amount;
        }

        private final ProgressTracker progressTracker = new ProgressTracker();

        @Override
        public ProgressTracker getProgressTracker() {
            return progressTracker;
        }

        @Suspendable
        @Override
        public SignedTransaction call() throws FlowException {

            /** Explicit selection of notary by CordaX500Name - argument can by coded in flows or parsed from config (Preferred)*/
            final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB"));
            // We get a reference to our own identity.
            Party issuer = getOurIdentity();

            /* ============================================================================
             *         TODO 1 - Create our TokenState to represent on-ledger tokens!
             * ===========================================================================*/
            // We create our new TokenState.
            TokenState tokenState = new TokenState(issuer, owner, amount);

            /* ============================================================================
             *      TODO 3 - Build our token issuance transaction to update the ledger!
             * ===========================================================================*/
            // We build our transaction.
            TransactionBuilder transactionBuilder = new TransactionBuilder.setNotary(notary).addOutputState(tokenState).addCommand(new TokenContract.Commands.Issue(), Arrays.asList(issuer.getOwningKey(), owner.getOwningKey()));

            /* ============================================================================
             *          TODO 2 - Write our TokenContract to control token issuance!
             * ===========================================================================*/
            // We check our transaction is valid based on its contracts.
            transactionBuilder.verify(getServiceHub());

            FlowSession session = initiateFlow(owner);

            // We sign the transaction with our private key, making it immutable.
            SignedTransaction signedTransaction = getServiceHub().signInitialTransaction(transactionBuilder);

            // The counterparty signs the transaction
            SignedTransaction fullySignedTransaction = subFlow(new CollectSignaturesFlow(signedTransaction, singletonList(session)));

            // We get the transaction notarised and recorded automatically by the platform.
            return subFlow(new FinalityFlow(fullySignedTransaction, singletonList(session)));
        }
    }

上記のコードでは、クラスTokenFlowInitiatorから継承するというクラスを作成しますFlowLogicFlowLogicクラスは、フローを作成していることをコーダに伝えます。

次に、2つの注釈とを追加@InitiatingFlow@StartableByRPCます。注釈は、この@InitiatingFlowフローが開始フローであることを示しています。一方、@StartableByRPC注釈により、RPCはフローを開始できます。

progressTracker次に、フローの各ステージをチェックポイントし、コードで各チェックポイントに到達したときに指定されたメッセージを出力するという変数を作成します。

次に、callフローの開始時にCordaが呼び出すメソッドを作成します。メソッド内ではcall、最初に公証人を作成し、それを。という変数に格納しますnotary。私たちは複数の当事者を扱っているので、当事者間の合意に達するために公証人のサービスが必要です。

IDを取得し、それを。という変数に格納しますissuer。次に、の新しいインスタンスを作成してトークンを作成し、、、、およびを引数としてTokenState渡します。issuerowneramount

次に、の新しいインスタンスを作成してトランザクション提案を作成しますTransactionBuilder。公証人を設定し、コマンドを追加し、トランザクションに署名するために、さまざまなメソッドをチェーンします。

最後に、メソッドFlowSessionを使用してカウンターパーティから開始します。InitiateFlowこのプロセスにより、状態をカウンターパーティに送信できます。CollectSignaturesFlow次に、サブフローを呼び出して署名を収集します。

レスポンダーフローの記述

レスポンダーフローは、カウンターパーティによって実行されます。トランザクションを受信して​​記録し、トランザクションが成功した場合は確認応答を返送することで発行者のフローに応答します。

workflows/src/main/java/com/template/flows次の名前の新しいJavaクラスに移動して作成しますTokenFlowResponder

package com.template.flows;

import co.paralleluniverse.fibers.Suspendable;
import net.corda.core.flows.*;
import net.corda.core.identity.Party;
import net.corda.core.transactions.SignedTransaction;


@InitiatedBy(TokenFlowInitiator.class)
    public static class TokenFlowResponder extends FlowLogic<Void>{
        //private variable
        private FlowSession counterpartySession;

        //Constructor
        public TokenFlowResponder(FlowSession counterpartySession) {
            this.counterpartySession = counterpartySession;
        }

        @Suspendable
        @Override
        public Void call() throws FlowException {
            SignedTransaction signedTransaction = subFlow(new SignTransactionFlow(counterpartySession) {});

            //Stored the transaction into data base.
            subFlow(new ReceiveFinalityFlow(counterpartySession, signedTransaction.getId()));
            return null;
        }
    }

上記のコードでは、クラスTokenFlowResponderから継承するというクラスを作成しますFlowLogic@InitiatedBy次に、アノテーションを追加し、TokenFlowInitiatorクラスを引数として渡して、フローを開始したコーダに通知します。

次に、トランザクションとフローイニシエーターから受け取った署名を検証するcallメソッドを作成します。オプションで、従来、安全のために一連のテストを実行するためにsubFlow呼び出される新しいメソッドを作成できます。checkTransaction

CorDappの実行

CorDappを開始するには、最初にプロジェクトのルートに移動し、次のコマンドを実行して、CorDappをデプロイする必要があります。

#Mac or Linux
./gradlew clean deployNodes

#Windows
gradlew.bat clean deployNodes

CorDappが正常にビルドされると、CorDappがインストールされた3つのノードが生成されます。これらはbuild/nodesフォルダにあります。

サンプルのCorDappを起動します

ノードとCorDappを起動するには、ルートディレクトリから次のコマンドを実行します。

#Mac or Linux
./build/nodes/runnodes

#Windows
.\build\nodes\runnodes.bat

上記のコードは、ノードごとに新しいターミナルウィンドウを開始します。各ターミナルの起動に少し時間がかかります。ノードの準備が整うと、ターミナルにウェルカムメッセージが表示されます。

CorDappとの対話

CorDappが正常に機能したかどうかを確認するには、次のコマンドを実行してフローを開始します。

flow start TokenFlowInitiator owner: PartyB, amount: 100

成功すると、確認メッセージが表示されます。

結論

ブロックチェーンは画期的なテクノロジーであり、プライベートブロックチェーンを使用するシステムのおかげで、規制対象の企業はこの変更から除外されません。Cordaのようなブロックチェーンプロジェクトは、データをプライベートに保ちながら、企業に必要な柔軟性を提供します。この記事では、Cordaをじっと見つめ、CorDappsの作成方法を学びました。

このチュートリアルを楽しんでいただければ幸いです。ご不明な点がございましたら、お気軽にコメントを残してください。

 ソース:https ://blog.logrocket.com/how-to-write-dapps-corda/

#dapp #corda #blockchain 

Cómo Escribir DApps en Corda

El lanzamiento de bitcoin el 3 de enero de 2009 puso en marcha tendencias como los activos digitales y las monedas digitales y, desde entonces, se han creado más cadenas de bloques como Ethereum y Solana. A pesar de tener diferentes características y casos de uso, estas cadenas de bloques tienen una cosa en común; fueron diseñados para operar democráticamente sin reguladores. Por lo tanto, este modelo no es adecuado para industrias reguladas, en las que los datos deben mantenerse confidenciales y compartirse entre partes de confianza. Por esta razón, existen cadenas de bloques privadas.

Una cadena de bloques privada es una cadena de bloques autorizada. Una cadena de bloques privada contiene entidades llamadas operadores de red que controlan la red y pueden configurar permisos y controles de acceso de los otros nodos. Para mantener la privacidad y la confianza, solo las entidades que participan en una transacción tendrán conocimiento de ella, mientras que otras no podrán acceder a ella.

Algunos ejemplos de plataformas digitales que utilizan cadenas de bloques privadas incluyen Hyperledger Fabric , Ripple y R3's Corda . En este artículo, exploraremos Corda y aprenderemos a crear CorDapps. ¡Empecemos!

Introducción a Corda

Corda es una tecnología de registro distribuido (DLT) peer-to-peer (P2P) autorizada que facilita el desarrollo de aplicaciones en mercados regulados. Con Corda, las partes pueden descubrirse libremente y realizar transacciones entre sí en una sola red abierta mientras confían en la identificación de los participantes de la red.

A la larga, Corda aspira a ser un libro mayor distribuido mundialmente compartido. Para ello, las numerosas soluciones que utilizan el software de Corda deben cumplir un conjunto de estándares y criterios comunes. Algunos de estos criterios, a menudo conocidos como principios de estado final, son los siguientes:

  • Identidad asegurada: Las partes tendrán confianza en las identidades de los participantes de la red. La identificación en Corda está representada por un certificado emitido por una autoridad relevante
  • Privacidad: las únicas personas que tienen acceso a la información de la transacción son aquellas que están involucradas en la transacción y aquellas que necesitan verificar el origen de la transacción.
  • Interoperabilidad: Corda está destinado a permitir que numerosas aplicaciones coexistan e interoperen en la misma red; se proporciona un conjunto definido de interfaces de contrato para optimizar la interoperabilidad de una amplia gama de proveedores

Componentes clave de CorDapps

CorDapp es una abreviatura de aplicación distribuida de Corda. CorDapps son aplicaciones distribuidas que se ejecutan en el nodo de Corda. Los siguientes son los componentes clave de una CorDapp:

estados

Los estados están hechos de datos. Realizan un seguimiento de los datos entre transacciones y son inmutables, lo que significa que no se pueden cambiar una vez que se han formado. En cambio, cualquier modificación debe dar como resultado la creación de un nuevo estado sucesor.

Contratos

Los contratos definen los criterios de validación que se aplicarán a las entradas y salidas de transacciones. Los contratos garantizan que los estados de entrada y salida de la transacción son válidos y que se evitan las transacciones no válidas. Pueden existir uno o más contratos en una CorDapp, cada uno de los cuales proporciona reglas para uno o más estados.

Flujos

Los flujos son las actividades que su CorDapp puede realizar en una red y constituyen la lógica comercial de su CorDapp. Los flujos permiten a las partes coordinar sus operaciones sin el uso de un controlador central.

Actas

Una transacción es una solicitud de actualización del libro mayor. Consume los estados de entrada actuales y genera otros nuevos para actualizar el libro mayor. Antes de que los nodos acepten una transacción, esta debe ser única, válida y estar firmada por las partes correspondientes.

Notario

Un notario es un servicio de la red de Corda que ayuda a evitar el gasto duplicado de los activos de la red. Lo hace garantizando que cada transacción solo incluya estados de entrada únicos que no hayan sido utilizados por una transacción anterior. Un notario también da una finalidad de transacción. Una transacción se considera finalizada después de que haya sido firmada por el notario.

Consenso

En Corda, puede establecer un consenso probando una transacción que sea válida y única. El consenso es un método que permite a los nodos ponerse de acuerdo sobre el estado actual de la red. Antes de que una transacción propuesta pueda ingresarse en el libro mayor, ambas partes deben estar de acuerdo en que es legal.

Primeros pasos con Corda

Crearemos una CorDapp para modelar la emisión de tokens en la cadena de bloques de Corda. Nuestro CorDapp hará un seguimiento del emisor del token, el titular y la cantidad que se emite.

Hay cuatro piezas de software necesarias para el desarrollo de CorDapp:

  • Java 8 JDK
  • IDEA IntelliJ
  • Git
  • Gradle, cualquier versión entre 5.1 y 5.6.4

configurando

Para configurar nuestra CorDapp, primero, clone la plantilla Corda Java de su repositorio de GitHub. Abra cordapp-template-javaen cualquier IDE de su elección. Usaré IntelliJ IDE.

Crear el Estado

Para reiterar, los estados son inmutables y realizan un seguimiento de los datos entre transacciones. Nuestra CorDapp tendrá un conjunto de atributos que almacenaremos en nuestro estado, como issuer, holdery amount.

Navegue /contracts/src/main/java/com/template/statesy cree una nueva clase de Java llamada TokenState:

package com.template.states

import com.template.contracts.TokenContract;
import net.corda.core.identity.AbstractParty;
import net.corda.core.contracts.BelongsToContract;
import net.corda.core.contracts.ContractState;
import net.corda.core.identity.Party;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;

@BelongsToContract(TokenContract.class)
public class TokenState implements ContractState {
    private Party issuer;
    private Party holder;
    private int amount;

    public TokenState(Party issuer, Party holder, int amount){
        this.issuer = issuer;
        this.holder = holder;
        this.amount = amount;
    }

    public Party getHolder() {
        return holder;
    }

    public Party getIssuer() {
        return issuer;
    }

    public int getAmount() {
        return amount;
    }

    @NotNull
    @Override
    public List<AbstractParty> getParticipants() {
        return Arrays.asList(issuer, holder);
    }
}

En el código anterior, creamos una clase llamada TokenStateque hereda de la ContractStateclase. La ContractStateclase le dice a Corda que estamos implementando un estado.

A continuación, añadimos la @BelongsToContractanotación, que establece la relación entre un estado y un contrato. Sin esto, su estado no sabe qué contrato se utiliza para verificarlo. Agregar esta anotación desencadena un error en IntelliJ porque aún tenemos que crear nuestro archivo TokenContract.

Luego, creamos tres atributos, issuer, holdery amount. Los atributos issuery holderreciben un tipo de Partyporque ambos representan entidades en el nodo.

A continuación, creamos tres métodos captadores para cada uno de los atributos. Finalmente, creamos un getParticipantsmétodo que define qué partes deben estar al tanto de la transacción. En nuestro caso, solo queremos que el issuery el holdersean conscientes de la transacción.

Crear el contrato

Para reiterar, los contratos definen las reglas de cómo los estados pueden evolucionar. Realizan ciertas validaciones antes de que una transacción se realice con éxito. Por lo tanto, cada estado está vinculado a un contrato.

Navegue /contracts/src/main/java/com/template/contractsy cree una nueva clase de Java llamada TokenContract:

package com.template.contracts

import net.corda.core.contracts.CommandData;
import net.corda.core.contracts.Contract;
import net.corda.core.transactions.LedgerTransaction;

import org.jetbrains.annotations.NotNull;
import com.template.states.TokenState;


public class TokenContract implements Contract {
    public static final String ID = "contracts.TokenContract";

    @Override
    public void verify(@NotNull LedgerTransaction tx) {

        if(tx.getCommands().size() != 1) {
            throw new IllegalArgumentException("expects only one command: ISSUE");
        }
        if(tx.getCommand(0).getValue() instanceof Commands.Issue){
            throw new IllegalArgumentException("issue command expected");
        }
        TokenState state = (TokenState) tx.getOutput(0);
        int amountIssued = state.getAmount();
        if (amountIssued <= 0){
            throw new IllegalArgumentException("amount must be greater than zero");
        }
        if(! (tx.getCommand(0).getSigners().contains(state.getIssuer().getOwningKey()))){
            throw new IllegalArgumentException("transaction must be signed by issuer");
        }
    }
    // Used to indicate the transaction's intent.
    public interface Commands extends CommandData {
        class Issue implements Commands {}
    }
}

En el código anterior, creamos una clase llamada TokenContractque hereda de la Contractclase. La Contractclase le dice a Corda que estamos implementando un contrato.

Primero, creamos un atributo llamado IDque identificará nuestro contrato al construir nuestra transacción en entornos de prueba. El IDatributo es puramente opcional.

Uno de los métodos que nos da la Contractclase que heredamos es el verifymétodo, que debemos anular. El verifymétodo toma transacciones como entrada y las evalúa contra reglas definidas. Una transacción es válida si el verifymétodo no arroja una excepción.

Con el código anterior, nuestro contrato realiza las siguientes comprobaciones:

  • Las transacciones deben ser firmadas por el emisor.
  • El monto debe ser mayor que cero
  • Solo issuese puede usar el comando
  • Estado de entrada inicial cero ya que es una emisión

Finalmente, dado que tenemos la intención de emitir el token a otra parte, creamos una clase llamada Issueque hereda de la Commandclase. La Commandclase se utiliza para indicar el tipo de acción que se está realizando.

Escribir el flujo de inicio

Para reiterar, los flujos contienen la lógica comercial de nuestra CorDapp. El flujo del iniciador lo ejecuta el nodo que inicia la transacción, que sería issueren nuestro caso.

Navegue workflows/src/main/java/com/template/flowsy cree una nueva clase de Java llamada FlowInitiator:

package com.template.flows;

import co.paralleluniverse.fibers.Suspendable;
import com.bootcamp.contracts.TokenContract;
import com.bootcamp.states.TokenState;
import net.corda.core.flows.*;
import net.corda.core.identity.CordaX500Name;
import net.corda.core.identity.Party;
import net.corda.core.transactions.SignedTransaction;
import net.corda.core.transactions.TransactionBuilder;
import net.corda.core.utilities.ProgressTracker;
import net.corda.core.contracts.CommandData;

import static java.util.Collections.singletonList;

    @InitiatingFlow
    @StartableByRPC
    public static class TokenFlowInitiator extends FlowLogic<SignedTransaction> {
        private final Party owner;
        private final int amount;

        public TokenFlowInitiator(Party owner, int amount) {
            this.owner = owner;
            this.amount = amount;
        }

        private final ProgressTracker progressTracker = new ProgressTracker();

        @Override
        public ProgressTracker getProgressTracker() {
            return progressTracker;
        }

        @Suspendable
        @Override
        public SignedTransaction call() throws FlowException {

            /** Explicit selection of notary by CordaX500Name - argument can by coded in flows or parsed from config (Preferred)*/
            final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB"));
            // We get a reference to our own identity.
            Party issuer = getOurIdentity();

            /* ============================================================================
             *         TODO 1 - Create our TokenState to represent on-ledger tokens!
             * ===========================================================================*/
            // We create our new TokenState.
            TokenState tokenState = new TokenState(issuer, owner, amount);

            /* ============================================================================
             *      TODO 3 - Build our token issuance transaction to update the ledger!
             * ===========================================================================*/
            // We build our transaction.
            TransactionBuilder transactionBuilder = new TransactionBuilder.setNotary(notary).addOutputState(tokenState).addCommand(new TokenContract.Commands.Issue(), Arrays.asList(issuer.getOwningKey(), owner.getOwningKey()));

            /* ============================================================================
             *          TODO 2 - Write our TokenContract to control token issuance!
             * ===========================================================================*/
            // We check our transaction is valid based on its contracts.
            transactionBuilder.verify(getServiceHub());

            FlowSession session = initiateFlow(owner);

            // We sign the transaction with our private key, making it immutable.
            SignedTransaction signedTransaction = getServiceHub().signInitialTransaction(transactionBuilder);

            // The counterparty signs the transaction
            SignedTransaction fullySignedTransaction = subFlow(new CollectSignaturesFlow(signedTransaction, singletonList(session)));

            // We get the transaction notarised and recorded automatically by the platform.
            return subFlow(new FinalityFlow(fullySignedTransaction, singletonList(session)));
        }
    }

En el código anterior, creamos una clase llamada TokenFlowInitiatorque hereda de la FlowLogicclase. La FlowLogicclase le dice a Corda que estamos creando un Flujo.

Luego, agregamos dos anotaciones, @InitiatingFlowy @StartableByRPC. La @InitiatingFlowanotación indica que este flujo es el flujo iniciador. Por otro lado, la @StartableByRPCanotación permite que RPC inicie el flujo.

A continuación, creamos una variable llamada progressTrackerque marca puntos de control en cada etapa del flujo y genera los mensajes especificados cuando se alcanza cada punto de control en el código.

A continuación, creamos el callmétodo, al que llama Corda cuando se inicia el flujo. Dentro del callmétodo, primero creamos un notario y lo almacenamos en una variable llamada notary. Dado que estamos tratando con múltiples partes, necesitamos un servicio de notario para llegar a un consenso entre las partes.

Obtenemos nuestra identidad y la almacenamos en una variable llamada issuer. A continuación, creamos nuestro token creando una nueva instancia de TokenStatey pasando los argumentos issuer, ownery .amount

Luego, construimos nuestra propuesta de transacción creando una nueva instancia de TransactionBuilder. Encadenamos diferentes métodos para configurar nuestro notario, agregar comandos y firmar la transacción.

Finalmente, comenzamos FlowSessioncon la contraparte utilizando el InitiateFlowmétodo. Este proceso nos permite enviar el estado a la contraparte. Luego llamamos al CollectSignaturesFlowsubflujo para recopilar firmas.

Escribir el flujo de respuesta

El flujo de respuesta lo ejecuta la contraparte. Recibe y registra la transacción, luego responde al flujo del emisor enviando un acuse de recibo si la transacción fue exitosa.

Navegue workflows/src/main/java/com/template/flowsy cree una nueva clase de Java llamada TokenFlowResponder:

package com.template.flows;

import co.paralleluniverse.fibers.Suspendable;
import net.corda.core.flows.*;
import net.corda.core.identity.Party;
import net.corda.core.transactions.SignedTransaction;


@InitiatedBy(TokenFlowInitiator.class)
    public static class TokenFlowResponder extends FlowLogic<Void>{
        //private variable
        private FlowSession counterpartySession;

        //Constructor
        public TokenFlowResponder(FlowSession counterpartySession) {
            this.counterpartySession = counterpartySession;
        }

        @Suspendable
        @Override
        public Void call() throws FlowException {
            SignedTransaction signedTransaction = subFlow(new SignTransactionFlow(counterpartySession) {});

            //Stored the transaction into data base.
            subFlow(new ReceiveFinalityFlow(counterpartySession, signedTransaction.getId()));
            return null;
        }
    }

En el código anterior, creamos una clase llamada TokenFlowResponderque hereda de la FlowLogicclase. Luego agregamos la @InitiatedByanotación y pasamos la TokenFlowInitiatorclase como argumento, diciéndole a Corda quién inició el flujo.

Luego, creamos el callmétodo con un subFlowque verificará la transacción y las firmas que recibió del iniciador del flujo. Opcionalmente, podemos crear convencionalmente un nuevo método llamado checkTransactionpara realizar una serie de pruebas solo para estar seguros.

Ejecutando nuestra CorDapp

Para iniciar nuestra CorDapp, primero debemos implementarla navegando a la raíz de nuestro proyecto y ejecutando los siguientes comandos:

#Mac or Linux
./gradlew clean deployNodes

#Windows
gradlew.bat clean deployNodes

Si nuestra CorDapp se construye con éxito, genera tres nodos con la CorDapp instalada en ellos. Estos se pueden encontrar en la build/nodescarpeta.

Inicie la aplicación CorDapp de muestra

Para iniciar los nodos y nuestra CorDapp, ejecute el siguiente comando desde nuestro directorio raíz:

#Mac or Linux
./build/nodes/runnodes

#Windows
.\build\nodes\runnodes.bat

El código anterior iniciará una nueva ventana de terminal para cada nodo. Dé a cada terminal algo de tiempo para comenzar y recibirá un mensaje de bienvenida en el terminal una vez que el nodo esté listo.

Interactuando con nuestra CorDapp

Para verificar si nuestro CorDapp funcionó correctamente, podemos intentar iniciar un flujo ejecutando el siguiente comando:

flow start TokenFlowInitiator owner: PartyB, amount: 100

Si tiene éxito, recibirá un mensaje de confirmación.

Conclusión

La cadena de bloques es una tecnología que cambia las reglas del juego, y las empresas reguladas no se quedan fuera de este cambio gracias a los sistemas que utilizan cadenas de bloques privadas. Los proyectos de cadena de bloques como Corda brindan a las empresas la flexibilidad que necesitan y, al mismo tiempo, mantienen la privacidad de los datos. En este artículo, exploramos cómo empezar con Corda, aprendiendo cómo hacer CorDapps.

Espero que hayas disfrutado este tutorial, y no dudes en dejar un comentario si tienes alguna pregunta.

 Fuente: https://blog.logrocket.com/how-to-write-dapps-corda/

#dapp #corda #blockchain