[JAVA] Comment utiliser l'API Chain

Quelle est la chaîne

Un projet blockchain mené par VISA Seule l'édition appelée Chain Core Developer Edition est open source. Veuillez vous référer à l'article sur la procédure de construction jusqu'à la construction de l'environnement Chain. Construction de l'environnement de la chaîne

Veuillez vous référer à l'exemple de code dans le document sur la page officielle. https://chain.com/docs/core/get-started/introduction

Fondamentalement, si vous regardez l'exemple de code, Javadoc et le code source du SDK, vous devez savoir quoi faire.

Les contrats, etc. n'ont pas encore été mis en œuvre.

Les informations telles que les transactions exécutées et les comptes créés peuvent également être confirmées sur le tableau de bord qui est affiché en accédant au port 1999 du serveur exécutant Chain avec un navigateur.

Explication de l'API

Classification

D'une manière générale, il y a l'exécution de requêtes de recherche et l'exécution de transactions telles que les envois de fonds. Une clé d'authentification n'est pas requise pour exécuter une requête, mais une clé d'authentification est requise pour exécuter une API qui provoque des transactions telles que des retraits.

Vous pouvez également voir l'ID interne, etc. dans Chaîne, La plupart sont créés en définissant un alias (alias) dans la devise, le compte, etc. Les requêtes et les transactions sont également exécutées à l'aide d'alias.

Préparation préalable

Notez l'URL, le port et la clé d'accès du serveur exécutant Chain.

	public static final String TARGET_URL = "http://XX.XXX.XX.XXX:1999/";
	public static final String TOKEN = "client:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
	public static final String KEY_ALIAS = "test";

Tout d'abord, générez une classe Client pour vous connecter au serveur.

Client client = new Client(TARGET_URL,TOKEN);

Si vous souhaitez exécuter une requête de recherche, vous n'avez besoin que de Client, mais si vous souhaitez exécuter une transaction, vous devez définir la clé d'authentification suivante.

MockHsm.Key key = null;
MockHsm.Key.Items keys = new MockHsm.Key.QueryBuilder().addAlias(ApiSettings.KEY_ALIAS).execute(client);
if (keys.hasNext()){
	key = keys.next();
}else{
	key = MockHsm.Key.create(client,ApiSettings.KEY_ALIAS);
}
HsmSigner.addKey(key, MockHsm.getSignerClient(client));

Si l'alias spécifié lors de la création de cette clé d'authentification est différent, une erreur d'authentification se produira et vous ne pourrez pas envoyer d'argent. La clé utilisée pour créer le compte de transfert doit également être utilisée pour authentifier la transaction de transfert.

MockHsm.Key key = MockHsm.Key.create(client);

Si vous créez une clé sans spécifier d'alias comme, un nombre illimité de clés anonymes sera créé, donc lors de sa création, spécifiez l'alias comme indiqué ci-dessous et créez-le avec une clé spécifique.

MockHsm.Key key = MockHsm.Key.create(client,ApiSettings.KEY_ALIAS);

Cela permet à la clé créée d'être récupérée par requête et réutilisée. En revanche, si vous ne spécifiez pas d'alias, vous ne pourrez pas spécifier explicitement la clé requise pour authentifier le compte lors de l'exécution d'une transaction. Ensuite, créez un compte, définissez les actifs (devise), transférez de l'argent, etc.

Exemples d'implémentation d'API individuels.

C'est juste pour référence, mais si vous utilisez l'exemple sur la page officielle tel quel, vous souffrirez d'erreurs dans la gestion de l'authentification.

Créer un compte

@Service
public class AccountService extends BaseService {

	private static final Logger LOGGER = LoggerFactory.getLogger(AccountService.class.getName());

	public String create(String account) throws ChainException{
		Client client = createClient();
		MockHsm.Key key = createKey(client);
		HsmSigner.addKey(key, MockHsm.getSignerClient(client));

		Account.Items accounts = new Account.QueryBuilder()
			.setFilter("alias=$1")
			.addFilterParameter(account)
			.execute(client);
		Account created = null;
		if (accounts.hasNext()){
			created = accounts.next();
			LOGGER.info("account is exists.");
		}else{
			created = new Account.Builder()
				.setAlias(account)
				.addRootXpub(key.xpub)
				.setQuorum(1)
				.create(client);
			LOGGER.info("account created.");
		}
		return created.alias;
	}
}

Ici, BaseService est la suivante.

@Service
public class BaseService {

	/**
	 *Obtenez un client de connexion
	 * @return client
	 * @throws ChainException
	 */
	protected Client createClient() throws ChainException{
		return new Client(ApiSettings.TARGET_URL,ApiSettings.TOKEN);
	}

	/**
	 *Obtenez une clé d'authentification commune
	 * @param client
	 * @return key
	 * @throws ChainException
	 */
	protected MockHsm.Key createKey(Client client) throws ChainException{
		MockHsm.Key key = null;
		MockHsm.Key.Items keys = new MockHsm.Key.QueryBuilder().addAlias(ApiSettings.KEY_ALIAS).execute(client);
		if (keys.hasNext()){
			key = keys.next();
		}else{
			key = MockHsm.Key.create(client,ApiSettings.KEY_ALIAS);
		}
		return key;
	}
}

Tout d'abord, j'utilise Query Builder pour rechercher un compte.

		Account.Items accounts = new Account.QueryBuilder()
			.setFilter("alias=$1")
			.addFilterParameter(account)
			.execute(client);

Toutes les classes principales telles que Account, Asset, Balance et MockHsm.Key ont des méthodes ** QueryBuilder () **. Vous pouvez rechercher de la même manière.

Dans ** setFilter ("condition") **, spécifiez la condition de recherche sous forme de chaîne de caractères. Les conditions qui peuvent être spécifiées ici sont décrites sur la page Objet API de la référence officielle de la documentation. https://chain.com/docs/core/reference/api-objects

Dans le ** addFilterParameter (account) ** suivant, spécifiez la chaîne de caractères à incorporer dans ** \ $ 1, $ 2 ** spécifiée par setFilter. Ici, la chaîne de caractères du nom de compte (alias) passée en argument est spécifiée. Après avoir défini le filtre, exécutez avec execute.

La requête est décrite sur la page suivante. https://chain.com/docs/core/build-applications/queries

Le résultat sera renvoyé par un itérateur tel que Account.Items et Balance.Items.

		if (accounts.hasNext()){
			created = accounts.next();

Je l'ai obtenu à.

C'est, par exemple

		while (balances.hasNext()) {
		  Balance b = balances.next();
		  LOGGER.info("balance of " + b.sumBy.get("asset_alias") + ": " + b.amount);
		}

Dès que vous le tournez avec tout comme

	    assets.forEachRemaining(s -> {
		      assetList.add(new AssetDto(s.id,s.alias));
	    });

Vous pouvez le tourner avec lambda comme.

Enfin, s'il n'y a pas de résultats de recherche, un nouveau compte est créé.

			created = new Account.Builder()
				.setAlias(account)
				.addRootXpub(key.xpub)
				.setQuorum(1)
				.create(client);
			LOGGER.info("account created.");

MockHsm.Key utilisé au cours de ce processus sera la clé créée à l'avance, mais la même clé doit être utilisée pour exécuter les transactions liées à ce compte. Il doit être créé pour chaque compte, mais comme la gestion est compliquée, une clé commune (alias) est utilisée ici.

Génération d'actifs (devises)

Ici, nous exécutons une transaction. En même temps que la devise est générée, la devise est transmise au compte spécifié. L'entrée et la sortie sont toujours un ensemble.

Définissez la devise dans l'action ** Émettre ** et L'action ** ControlWithAccount ** transmet la devise générée au compte spécifié.

@Service
public class IssueService extends BaseService {

	private static final Logger LOGGER = LoggerFactory.getLogger(IssueService.class.getName());

	public void issue(String assetName,String issueAccount,Long amount) throws ChainException{

		Client client = createClient();
		MockHsm.Key key = createKey(client);
		HsmSigner.addKey(key, MockHsm.getSignerClient(client));
		
		//Générer si la devise de assetName n'est pas définie.
		if (!isExistAsset(assetName,client)){
		    new Asset.Builder()
		      .setAlias(assetName)
		      .addRootXpub(key.xpub)
		      .setQuorum(1)
		      .create(client);
		}
		//Transaction de définition de devise.
		//De l'action Issue à l'action ControlWithAccount, le montant de la devise assetName est distribué à issueAccount.
		Transaction.Template issuanceToProgram = new Transaction.Builder()
	      .addAction(new Transaction.Action.Issue()
	        .setAssetAlias(assetName)
	        .setAmount(amount)
	      ).addAction(new Transaction.Action.ControlWithAccount()
	        .setAccountAlias(issueAccount)
	        .setAssetAlias(assetName)
	        .setAmount(amount)
	      ).build(client);
		//Signature et exécution des transactions
	    Transaction.Template signedIssuanceToProgram = HsmSigner.sign(issuanceToProgram);
	    Transaction.submit(client, signedIssuanceToProgram);
	}

	private boolean isExistAsset(String assetName,Client client) throws ChainException {

		Asset.Items assets = new Asset.QueryBuilder()
	      .setFilter("alias=$1")
	      .addFilterParameter(assetName)
	      .execute(client);

	    if (assets.hasNext()){
	    	return true;
	    }
	    return false;
	}
}

Recherche d'actifs (devise) prédéfinie

Écrit comme toute autre requête.

@Service
public class AssetQueryService extends BaseService {

	public List<AssetDto> getAssetList(String assetName) throws ChainException {

		Client client = createClient();

	    Asset.Items assets = new Asset.QueryBuilder()
	      .setFilter("alias=$1")
	      .addFilterParameter(assetName)
	      .execute(client);

	    List<AssetDto> assetList = new ArrayList<>();
	    assets.forEachRemaining(s -> {
		      assetList.add(new AssetDto(s.id,s.alias));
	    });
	    return assetList;
	}
}

Vérifier le solde

Ceci est également écrit de la même manière sauf que la classe Balance est utilisée. L'exemple suivant utilise deux paramètres de recherche.

@Service
public class BalanceService extends BaseService {

	private static final Logger LOGGER = LoggerFactory
			.getLogger(BalanceService.class.getName());

	public ResponseBalanceDto getBalance(String assetName, String account)
			throws ChainException {
		Client client = createClient();

		Balance.Items balances = new Balance.QueryBuilder()
			.setFilter("account_alias=$1 AND asset_alias=$2")
			.addFilterParameter(account)
			.addFilterParameter(assetName)
			.execute(client);
		Balance balance = null;
		ResponseBalanceDto responseDto = new ResponseBalanceDto();
		if (balances.hasNext()){
			balance = balances.next();
			responseDto.setBalance(balance.amount);
			LOGGER.info("account:{} asset:{} amount:{} ",account,assetName,balance.amount);
		}
		return responseDto;
	}
}

transfert d'argent

Avec l'action ** SpendFromAccount **, retirez la devise de l'expéditeur et L'action ** ControlWithAccount ** transmet la devise au destinataire. Faites attention à Key etc. car la transaction n'est pas exécutée uniquement par alias.

@Service
public class TransferService extends BaseService {

	private static final Logger LOGGER = LoggerFactory.getLogger(TransferService.class.getName());

	/**
	 *Exécution des remises
	 * @param du compte source de remise de compte
	 * @param au compte de remise de compte
	 * @param assetName Nom de la devise
	 * @montant du paramètre montant
	 * @throws ChainException
	 */
	public void transfer(String fromAccount, String toAccount,
			String assetName, Long amount) throws ChainException {
		Client client = createClient();
		MockHsm.Key key = createKey(client);
		HsmSigner.addKey(key, MockHsm.getSignerClient(client));
		Transaction.Template transfertran = new Transaction.Builder()
				.addAction(
						new Transaction.Action.SpendFromAccount()
								.setAccountAlias(fromAccount)
								.setAssetAlias(assetName).setAmount(amount))
				.addAction(
						new Transaction.Action.ControlWithAccount()
								.setAccountAlias(toAccount)
								.setAssetAlias(assetName).setAmount(amount))
				.build(client);

		Transaction.Template signedTransfertran = HsmSigner.sign(transfertran);
		Transaction.submit(client, signedTransfertran);

	}
}

key Chain,blockchain,API

Recommended Posts

Comment utiliser l'API Chain
Comment utiliser Map
Comment utiliser rbenv
Comment utiliser with_option
Comment utiliser fields_for
Comment utiliser java.util.logging
Comment utiliser la carte
Comment utiliser collection_select
Comment utiliser Twitter4J
Comment utiliser active_hash! !!
Comment utiliser MapStruct
Comment utiliser TreeSet
[Comment utiliser l'étiquette]
Comment utiliser l'identité
Comment utiliser le hachage
Comment utiliser Dozer.mapper
Comment utiliser Gradle
Comment utiliser org.immutables
Comment utiliser java.util.stream.Collector
Comment utiliser VisualVM
Comment utiliser Map
Comment utiliser l'API Java avec des expressions lambda
[Java] Comment utiliser Map
Comment utiliser Queue avec priorité
[Rails] Comment utiliser enum
Comment utiliser java Facultatif
Comment utiliser JUnit (débutant)
Comment utiliser le retour Ruby
[Rails] Comment utiliser enum
Comment utiliser @Builder (Lombok)
Comment utiliser la classe Java
Comment utiliser Big Decimal
[Java] Comment utiliser removeAll ()
Comment utiliser String [] args
Comment utiliser la jonction de rails
Comment utiliser Java Map
Ruby: Comment utiliser les cookies
Comment utiliser Dependant :: Destroy
Comment utiliser Eclipse Debug_Shell
Comment utiliser Apache POI
[Rails] Comment utiliser la validation
Comment utiliser les variables Java
[Rails] Comment utiliser authenticate_user!
Comment utiliser GC Viewer
Comment utiliser Lombok maintenant
[Création] Comment utiliser JUnit
[Rails] Comment utiliser Scope
Résumé de l'API de communication Java (1) Comment utiliser Socket
Résumé de l'API de communication Java (3) Comment utiliser SocketChannel
Résumé de l'API de communication Java (2) Comment utiliser HttpUrlConnection
Comment utiliser la méthode link_to