1678972620
このチュートリアルでは、Mac でデフォルトのブラウザを変更する方法を学びます。Mac の既定のブラウザーを任意のブラウザーに変更する
有名なトラックパッドと Retina ディスプレイとは別に、Apple のファーストパーティ アプリは Mac コンピュータのハイライトです。便利な Notes アプリでも、Apple シリコン Mac の新しい合理化された Safari アプリでもかまいません。しかし、Mac の既定のアプリが気に入らない場合はどうすればよいでしょうか? Windows から切り替える場合はどうなりますか? 心配しないで。Mac の既定のブラウザーを変更する方法を説明します。
デフォルト ブラウザの変更は、理想的にはシンプルで簡単なプロセスです。ただし、macOS のオプションは設定アプリ内にあり、通常は見つけられない場所にあります。この記事を読むまでは。Mac を手に取り、以下の手順に従ってデフォルトのブラウザをお気に入りのブラウザに設定します。
すでに述べたように、Safari は、最初に Mac を入手したときのデフォルトのブラウザです。Safari は Apple 独自のアプリであるため、これは明らかです。新しい Safari はカスタマイズ可能で、Apple シリコン Mac 向けに十分に最適化されていますが、多くのユーザーはそのデザインを気に入らないかもしれません。
Users who are switching from Windows or other operating systems may also find the features of Safari limiting. Furthermore, if you use Chrome extensions or specific features only found on certain web browsers, you would want to carry them over to your Mac. This is why you would want to get another browser on your Mac.
If you’re invested in the Google ecosystem, all it takes is a few clicks to set Chrome as the default browser on your Mac. Here’s how to switch from Safari to Chrome, Firefox, or just about any browser of your choice on a Mac.
The steps we’ve mentioned below apply to Macs running macOS Ventura and newer. If you’re running an older version of macOS, we suggest updating to the latest version so that the instructions align with your OS. Once you’ve updated, you can follow the steps below.
ステップ 1: お使いの Mac に任意のブラウザーをダウンロードしてインストールします。
Google Chrome、Mozilla Firefox、Microsoft Edge、または任意の他のブラウザをダウンロードできます。混乱している場合は、バッテリーを節約するこれらの Web ブラウザーを調べてください。
ステップ 2: インストールが完了したら、Mac のホーム画面に移動します。左上隅にある Apple ロゴをクリックし、[システム設定] を選択します。
ステップ 3: 左ペインの [デスクトップとドック] メニューに移動します。
ステップ 4: [Windows & Apps] セクションが表示されるまで、右側を下にスクロールします。
ステップ 5: ここに、「既定の Web ブラウザー」オプションがあります。その横にあるドロップダウンメニューをクリックします。
ステップ 6: メニューからお好みの Web ブラウザーを選択します。
これで、Chrome が Mac の既定のブラウザに設定されました。もちろん、他のブラウザも動作します。しかし、既定のブラウザを変更する設定が [デスクトップとドック] セクションに隠されているのはなぜですか? さて、それが macOS であり、その悪ふざけです!
手順に従っても、Mac の既定のブラウザーを変更できませんか? ここにいくつかの簡単な解決策があります。
1. Safari は Mac に最適な Web ブラウザーですか?
Safari は Apple によって作成されているため、Mac 用に最適化されています。Apple シリコンを搭載した Mac をお持ちの場合、Safari はバッテリーの消費を最小限に抑えながら最高のパフォーマンスを提供する可能性があります。そのため、パフォーマンスに基づいて Mac で使用するのに最適なブラウザーかもしれませんが、機能に関しては必ずしも最高であるとは限りません。
2. Google Chrome は M1 および M2 Mac 用に最適化されていますか?
はい、Google は Apple シリコン Mac 用のバージョンの Chrome をリリースしたので、M1 または M2 Mac を使用している場合はカバーされます。
必要がなければ、強制的に Safari を使用する必要はありません。ガイドに従って、Mac の既定のブラウザーを任意のブラウザーに変更するだけで、自宅にいるように感じることができます。では、Mac で使用している Web ブラウザとその理由は何ですか? 以下のコメントでお知らせください。
#browser #mac
1678972620
このチュートリアルでは、Mac でデフォルトのブラウザを変更する方法を学びます。Mac の既定のブラウザーを任意のブラウザーに変更する
有名なトラックパッドと Retina ディスプレイとは別に、Apple のファーストパーティ アプリは Mac コンピュータのハイライトです。便利な Notes アプリでも、Apple シリコン Mac の新しい合理化された Safari アプリでもかまいません。しかし、Mac の既定のアプリが気に入らない場合はどうすればよいでしょうか? Windows から切り替える場合はどうなりますか? 心配しないで。Mac の既定のブラウザーを変更する方法を説明します。
デフォルト ブラウザの変更は、理想的にはシンプルで簡単なプロセスです。ただし、macOS のオプションは設定アプリ内にあり、通常は見つけられない場所にあります。この記事を読むまでは。Mac を手に取り、以下の手順に従ってデフォルトのブラウザをお気に入りのブラウザに設定します。
すでに述べたように、Safari は、最初に Mac を入手したときのデフォルトのブラウザです。Safari は Apple 独自のアプリであるため、これは明らかです。新しい Safari はカスタマイズ可能で、Apple シリコン Mac 向けに十分に最適化されていますが、多くのユーザーはそのデザインを気に入らないかもしれません。
Users who are switching from Windows or other operating systems may also find the features of Safari limiting. Furthermore, if you use Chrome extensions or specific features only found on certain web browsers, you would want to carry them over to your Mac. This is why you would want to get another browser on your Mac.
If you’re invested in the Google ecosystem, all it takes is a few clicks to set Chrome as the default browser on your Mac. Here’s how to switch from Safari to Chrome, Firefox, or just about any browser of your choice on a Mac.
The steps we’ve mentioned below apply to Macs running macOS Ventura and newer. If you’re running an older version of macOS, we suggest updating to the latest version so that the instructions align with your OS. Once you’ve updated, you can follow the steps below.
ステップ 1: お使いの Mac に任意のブラウザーをダウンロードしてインストールします。
Google Chrome、Mozilla Firefox、Microsoft Edge、または任意の他のブラウザをダウンロードできます。混乱している場合は、バッテリーを節約するこれらの Web ブラウザーを調べてください。
ステップ 2: インストールが完了したら、Mac のホーム画面に移動します。左上隅にある Apple ロゴをクリックし、[システム設定] を選択します。
ステップ 3: 左ペインの [デスクトップとドック] メニューに移動します。
ステップ 4: [Windows & Apps] セクションが表示されるまで、右側を下にスクロールします。
ステップ 5: ここに、「既定の Web ブラウザー」オプションがあります。その横にあるドロップダウンメニューをクリックします。
ステップ 6: メニューからお好みの Web ブラウザーを選択します。
これで、Chrome が Mac の既定のブラウザに設定されました。もちろん、他のブラウザも動作します。しかし、既定のブラウザを変更する設定が [デスクトップとドック] セクションに隠されているのはなぜですか? さて、それが macOS であり、その悪ふざけです!
手順に従っても、Mac の既定のブラウザーを変更できませんか? ここにいくつかの簡単な解決策があります。
1. Safari は Mac に最適な Web ブラウザーですか?
Safari は Apple によって作成されているため、Mac 用に最適化されています。Apple シリコンを搭載した Mac をお持ちの場合、Safari はバッテリーの消費を最小限に抑えながら最高のパフォーマンスを提供する可能性があります。そのため、パフォーマンスに基づいて Mac で使用するのに最適なブラウザーかもしれませんが、機能に関しては必ずしも最高であるとは限りません。
2. Google Chrome は M1 および M2 Mac 用に最適化されていますか?
はい、Google は Apple シリコン Mac 用のバージョンの Chrome をリリースしたので、M1 または M2 Mac を使用している場合はカバーされます。
必要がなければ、強制的に Safari を使用する必要はありません。ガイドに従って、Mac の既定のブラウザーを任意のブラウザーに変更するだけで、自宅にいるように感じることができます。では、Mac で使用している Web ブラウザとその理由は何ですか? 以下のコメントでお知らせください。
#browser #mac
1614246541
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.
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.
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.
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.
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
1598511081
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.
#golang #mac #vscode #go #linux #mac os x
1651550028
Le lancement du bitcoin le 3 janvier 2009 a mis en mouvement des tendances telles que les actifs numériques et les monnaies numériques, et depuis lors, davantage de chaînes de blocs comme Ethereum et Solana ont été créées. Malgré des fonctionnalités et des cas d'utilisation différents, ces blockchains ont une chose en commun ; ils ont été conçus pour fonctionner démocratiquement sans régulateurs. Par conséquent, ce modèle n'est pas adapté aux industries réglementées, dans lesquelles les données doivent rester confidentielles et partagées entre des parties de confiance. Pour cette raison, des blockchains privées existent.
Une blockchain privée est une blockchain autorisée. Une blockchain privée contient des entités appelées opérateurs de réseau qui contrôlent le réseau et peuvent configurer les autorisations et les contrôles d'accès des autres nœuds. Pour maintenir la confidentialité et la confiance, seules les entités participant à une transaction en auront connaissance, tandis que les autres ne pourront pas y accéder.
Quelques exemples de plates-formes numériques qui utilisent des chaînes de blocs privées incluent Hyperledger Fabric , Ripple et Corda de R3 . Dans cet article, nous allons explorer Corda et apprendre à créer des CorDapps. Commençons!
Corda est une technologie de registre distribué peer-to-peer (P2P) autorisée qui facilite le développement d'applications sur les marchés réglementés. Avec Corda, les parties peuvent librement découvrir et effectuer des transactions les unes avec les autres dans un seul réseau ouvert tout en ayant confiance dans l'identification des participants au réseau.
À long terme, Corda aspire à être un grand livre partagé distribué dans le monde entier. Pour ce faire, les nombreuses solutions qui utilisent le logiciel Corda doivent respecter un ensemble de normes et de critères communs. Certains de ces critères, souvent appelés principes de l'état final, sont les suivants :
CorDapp est un raccourci pour l'application distribuée Corda. Les CorDapps sont des applications distribuées qui s'exécutent sur le nœud Corda. Voici les composants clés d'un CorDapp :
Les états sont constitués de données. Ils gardent une trace des données entre les transactions et sont immuables, ce qui signifie qu'ils ne peuvent pas être modifiés après leur formation. Toute modification doit plutôt entraîner la création d'un nouvel État successeur.
Les contrats définissent les critères de validation qui seront appliqués aux entrées et sorties des transactions. Les contrats garantissent que les états d'entrée et de sortie des transactions sont valides et que les transactions invalides sont évitées. Un ou plusieurs contrats peuvent exister dans un CorDapp, chacun fournissant des règles pour un ou plusieurs états.
Les flux sont les activités que votre CorDapp peut entreprendre sur un réseau, et ils constituent la logique métier de votre CorDapp. Les flux permettent aux parties de coordonner leurs opérations sans recourir à un contrôleur central.
Une transaction est une demande de mise à jour du registre. Il consomme les états d'entrée actuels et en génère de nouveaux pour mettre à jour le grand livre. Avant qu'une transaction ne soit acceptée par les nœuds, une transaction doit être unique, valide et signée par les parties appropriées.
Un notaire est un service du réseau Corda qui permet d'éviter les dépenses en double des actifs du réseau. Il le fait en garantissant que chaque transaction ne comprend que des états d'entrée uniques qui n'ont pas été utilisés par une transaction précédente. Un notaire donne également une finalité à la transaction. Une transaction est considérée comme conclue après sa signature par le notaire.
Dans Corda, vous pouvez établir un consensus en prouvant qu'une transaction est à la fois valide et unique. Le consensus est une méthode qui permet aux nœuds de s'entendre sur l'état actuel du réseau. Avant qu'une transaction proposée puisse être inscrite dans le grand livre, les deux parties doivent convenir qu'elle est légale.
Nous allons créer une CorDapp pour modéliser l'émission de jetons sur la blockchain Corda. Notre CorDapp gardera une trace de l'émetteur du jeton, du détenteur et du montant émis.
Il existe quatre logiciels requis pour le développement de CorDapp :
Pour configurer notre CorDapp, commencez par cloner le modèle Corda Java à partir de leur dépôt GitHub. Ouvrir cordapp-template-java
dans n'importe quel IDE de votre choix. Je vais utiliser IntelliJ IDE.
Pour rappel, les états sont immuables et gardent une trace des données entre les transactions. Notre CorDapp va avoir un ensemble d'attributs que nous allons stocker sur notre état, comme issuer
, holder
et amount
.
Naviguez jusqu'à /contracts/src/main/java/com/template/states
et créez une nouvelle classe Java appeléeTokenState
:
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);
}
}
Dans le code ci-dessus, nous créons une classe appelée TokenState
qui hérite de la ContractState
classe. La ContractState
classe indique à Corda que nous implémentons un état.
Ensuite, nous ajoutons l' @BelongsToContract
annotation, qui établit la relation entre un état et un contrat. Sans cela, votre état ne sait pas quel contrat est utilisé pour le vérifier. L'ajout de cette annotation déclenche une erreur dans IntelliJ car nous n'avons pas encore créé notre fichier TokenContract
.
Ensuite, nous créons trois attributs, issuer
, holder
et amount
. Les attributs issuer
et holder
reçoivent le type Party
car ils représentent tous deux des entités sur le nœud.
Ensuite, nous créons trois méthodes getter pour chacun des attributs. Enfin, nous créons une getParticipants
méthode qui définit quelles parties doivent être informées de la transaction. Dans notre cas, nous voulons seulement que le issuer
et le holder
soient au courant de la transaction.
Pour rappel, les contrats définissent les règles d'évolution des États. Ils effectuent certaines validations avant qu'une transaction ne se déroule avec succès. Par conséquent, chaque état est lié à un contrat.
Naviguez jusqu'à /contracts/src/main/java/com/template/contracts
et créez une nouvelle classe Java appeléeTokenContract
:
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 {}
}
}
Dans le code ci-dessus, nous créons une classe appelée TokenContract
qui hérite de la Contract
classe. La Contract
classe dit à Corda que nous mettons en œuvre un contrat.
Tout d'abord, nous créons un attribut appelé ID
qui identifiera notre contrat lors de la construction de notre transaction dans des environnements de test. L' ID
attribut est purement facultatif.
L'une des méthodes qui nous est donnée par la Contract
classe dont nous avons hérité est la verify
méthode, que nous devons redéfinir. La verify
méthode prend les transactions en entrée et les évalue par rapport à des règles définies. Une transaction est valide si la verify
méthode ne lève pas d'exception.
Avec le code ci-dessus, notre contrat effectue les vérifications suivantes :
issue
commande peut être utiliséeEnfin, puisque nous avons l'intention d'émettre le jeton à une autre partie, nous créons une classe appelée Issue
qui hérite de la Command
classe. La Command
classe est utilisée pour indiquer le type d'action en cours d'exécution.
Pour rappel, les flux contiennent la logique métier de notre CorDapp. Le flux initiateur est exécuté par le nœud initiant la transaction, qui serait le issuer
dans notre cas.
Naviguez jusqu'à workflows/src/main/java/com/template/flows
et créez une nouvelle classe Java appeléeFlowInitiator
:
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)));
}
}
Dans le code ci-dessus, nous créons une classe appelée TokenFlowInitiator
qui hérite de la FlowLogic
classe. La FlowLogic
classe dit à Corda que nous créons un flux.
Ensuite, nous ajoutons deux annotations, @InitiatingFlow
et @StartableByRPC
. L' @InitiatingFlow
annotation indique que ce flux est le flux initiateur. D'autre part, l' @StartableByRPC
annotation permet à RPC de démarrer le flux.
Ensuite, nous créons une variable appelée progressTracker
qui contrôle chaque étape du flux et génère les messages spécifiés lorsque chaque point de contrôle est atteint dans le code.
Ensuite, nous créons la call
méthode, que Corda appelle au démarrage du flux. Dans la call
méthode, nous créons d'abord un notaire et le stockons dans une variable appelée notary
. Puisque nous traitons avec plusieurs parties, nous avons besoin d'un service de notaire pour parvenir à un consensus entre les parties.
Nous obtenons notre identité et la stockons dans une variable appelée issuer
. Ensuite, nous créons notre jeton en créant une nouvelle instance de TokenState
et en passant les arguments issuer
, owner
et .amount
Ensuite, nous construisons notre proposition de transaction en créant une nouvelle instance de TransactionBuilder
. Nous enchaînons différentes méthodes pour paramétrer notre notaire, ajouter des commandes, et signer la transaction.
Enfin, nous commençons a FlowSession
avec la contrepartie en utilisant la InitiateFlow
méthode. Ce processus nous permet d'envoyer l'état à la contrepartie. Nous appelons ensuite le sous- CollectSignaturesFlow
flux pour collecter les signatures.
Le flux du répondeur est géré par la contrepartie. Il reçoit et enregistre la transaction, puis répond au flux de l'émetteur en renvoyant un accusé de réception si la transaction a réussi.
Naviguez jusqu'à workflows/src/main/java/com/template/flows
et créez une nouvelle classe Java appeléeTokenFlowResponder
:
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;
}
}
Dans le code ci-dessus, nous créons une classe appelée TokenFlowResponder
qui hérite de la FlowLogic
classe. Nous ajoutons ensuite l' @InitiatedBy
annotation et transmettons la TokenFlowInitiator
classe en tant qu'argument, indiquant à Corda qui a initié le flux.
Ensuite, nous créons la call
méthode avec a subFlow
qui vérifiera la transaction et les signatures qu'elle a reçues de l'initiateur du flux. Facultativement, nous pouvons créer de manière conventionnelle une nouvelle méthode appelée checkTransaction
à effectuer une série de tests juste pour être sûr.
Pour démarrer notre CorDapp, nous devons d'abord le déployer en naviguant à la racine de notre projet et en exécutant les commandes suivantes :
#Mac or Linux
./gradlew clean deployNodes
#Windows
gradlew.bat clean deployNodes
Si notre CorDapp se construit avec succès, il génère trois nœuds avec le CorDapp installé dessus. Ceux-ci peuvent être trouvés dans le build/nodes
dossier.
Pour démarrer les nœuds et notre CorDapp, exécutez la commande suivante depuis notre répertoire racine :
#Mac or Linux
./build/nodes/runnodes
#Windows
.\build\nodes\runnodes.bat
Le code ci-dessus ouvrira une nouvelle fenêtre de terminal pour chaque nœud. Donnez à chaque terminal un peu de temps pour démarrer et vous recevrez un message de bienvenue sur le terminal une fois que le nœud sera prêt.
Pour vérifier si notre CorDapp a fonctionné avec succès, nous pouvons essayer de démarrer un flux en exécutant la commande suivante :
flow start TokenFlowInitiator owner: PartyB, amount: 100
La blockchain est une technologie qui change la donne, et les entreprises réglementées ne sont pas en reste grâce à des systèmes qui utilisent des blockchains privées. Les projets de blockchain comme Corda offrent aux entreprises la flexibilité dont elles ont besoin tout en préservant la confidentialité des données. Dans cet article, nous avons exploré comment démarrer avec Corda, en apprenant à créer des CorDapps.
J'espère que ce tutoriel vous a plu, et n'hésitez pas à laisser un commentaire si vous avez des questions.
1651673160
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!
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:
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:
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.
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.
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.
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.
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.
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.
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:
Para configurar nuestra CorDapp, primero, clone la plantilla Corda Java de su repositorio de GitHub. Abra cordapp-template-java
en cualquier IDE de su elección. Usaré IntelliJ IDE.
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
, holder
y amount
.
Navegue /contracts/src/main/java/com/template/states
y 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 TokenState
que hereda de la ContractState
clase. La ContractState
clase le dice a Corda que estamos implementando un estado.
A continuación, añadimos la @BelongsToContract
anotació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
, holder
y amount
. Los atributos issuer
y holder
reciben un tipo de Party
porque ambos representan entidades en el nodo.
A continuación, creamos tres métodos captadores para cada uno de los atributos. Finalmente, creamos un getParticipants
método que define qué partes deben estar al tanto de la transacción. En nuestro caso, solo queremos que el issuer
y el holder
sean conscientes de la transacción.
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/contracts
y 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 TokenContract
que hereda de la Contract
clase. La Contract
clase le dice a Corda que estamos implementando un contrato.
Primero, creamos un atributo llamado ID
que identificará nuestro contrato al construir nuestra transacción en entornos de prueba. El ID
atributo es puramente opcional.
Uno de los métodos que nos da la Contract
clase que heredamos es el verify
método, que debemos anular. El verify
método toma transacciones como entrada y las evalúa contra reglas definidas. Una transacción es válida si el verify
método no arroja una excepción.
Con el código anterior, nuestro contrato realiza las siguientes comprobaciones:
issue
se puede usar el comandoFinalmente, dado que tenemos la intención de emitir el token a otra parte, creamos una clase llamada Issue
que hereda de la Command
clase. La Command
clase se utiliza para indicar el tipo de acción que se está realizando.
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 issuer
en nuestro caso.
Navegue workflows/src/main/java/com/template/flows
y 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 TokenFlowInitiator
que hereda de la FlowLogic
clase. La FlowLogic
clase le dice a Corda que estamos creando un Flujo.
Luego, agregamos dos anotaciones, @InitiatingFlow
y @StartableByRPC
. La @InitiatingFlow
anotación indica que este flujo es el flujo iniciador. Por otro lado, la @StartableByRPC
anotación permite que RPC inicie el flujo.
A continuación, creamos una variable llamada progressTracker
que 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 call
método, al que llama Corda cuando se inicia el flujo. Dentro del call
mé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 TokenState
y pasando los argumentos issuer
, owner
y .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 FlowSession
con la contraparte utilizando el InitiateFlow
método. Este proceso nos permite enviar el estado a la contraparte. Luego llamamos al CollectSignaturesFlow
subflujo para recopilar firmas.
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/flows
y 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 TokenFlowResponder
que hereda de la FlowLogic
clase. Luego agregamos la @InitiatedBy
anotación y pasamos la TokenFlowInitiator
clase como argumento, diciéndole a Corda quién inició el flujo.
Luego, creamos el call
método con un subFlow
que verificará la transacción y las firmas que recibió del iniciador del flujo. Opcionalmente, podemos crear convencionalmente un nuevo método llamado checkTransaction
para realizar una serie de pruebas solo para estar seguros.
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/nodes
carpeta.
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.
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.
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/