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.
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.
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.
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.
@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.
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;
}
}
É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;
}
}
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;
}
}
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