Tutoriel de développement IBAX
Guide de démarrage
- Déployer le premier contrat intelligent via l'outil en ligne de commande
- Développement de l'écosystème de l'outil en ligne de commande
Déploiement
- Déployer une application à l'aide des outils en ligne de commande
- Configuration écologique à l'aide de l'outil en ligne de commande
Guide Avancé
Déployer le premier smart contract via l'outil en ligne de commande
Nous allons déployer des smart contracts sur la blockchain IBAX via l'outil en ligne de commande et apprendre comment invoquer des smart contracts. En tant que premier smart contract, nous l'avons déployé sur le réseau de test local. Pour savoir comment déployer un réseau local, vous pouvez vous référer à Déploiement du réseau, ainsi vous pouvez le déployer et l'exécuter comme vous le souhaitez sans aucun surcoût.
Créer une application
Appelez le contrat @1NewApplication pour créer l'application, qui a un paramètre de nom d'application et un paramètre de permission de modification.
1 $ ibax-cli console
2
3 Bienvenue dans la console IBAX !
4 Pour quitter, appuyez sur ctrl-d ou tapez exit
5 >callContract @1NewApplication {"Name": "testapp", "Conditions": "ContractConditions(\"@1DeveloperCondition\")"}
6
7 {
8 "block_id": 1217,
9 "hash": "6327161d2202c33c06d34ab4ed9b509c05fc2cbb15cf260c6d3d404a6f640028",
10 "penalty": 0,
11 "err": "31"
12 }
Les éléments suivants sont expliqués par ligne :
- Ligne 1, démarrer le terminal de ligne de commande
- Ligne 5, appeler le contrat @1NewApplication pour créer une application avec
le nom d'application
testappet la permission de modification de l'application@1DeveloperConditionavec la permission du développeur - Ligne 8, l'identifiant de bloc généré par la transaction
- Ligne 9, le hachage de bloc généré par la transaction
- Ligne 10, si l'exécution de la transaction échoue (0 : pas de pénalité, 1 : pénalité)
- Ligne 11, si l'exécution de la transaction échoue, un message d'erreur est renvoyé, et si l'identifiant de bloc est renvoyé, le champ err est l'identifiant de l'application
Bien sûr, si vous souhaitez voir quels champs et types de champs sont
disponibles dans ce contrat, vous pouvez appeler la méthode getContractInfo,
qui renverra les informations sur le contrat comme suit:
>getContractInfo @1NewApplication
{
"id": 5022,
"state": 1,
"tableid": "22",
"walletid": "0",
"tokenid": "1",
"address": "0000-0000-0000-0000-0000",
"fields": [
{
"name": "Name",
"type": "string",
"optional": false
},
{
"name": "Conditions",
"type": "string",
"optional": false
},
{
"name": "VotingId",
"type": "int",
"optional": true
}
],
"name": "@1NewApplication",
"app_id": 1,
"ecosystem": 1,
"conditions": "ContractConditions(\"@1DeveloperCondition\")"
}
Le champ fields est constitué des paramètres du contrat, incluant le nom du
paramètre name, type, optional, Name et Conditions sont requis,
VotingId est optionnel, consultez la méthode API
contract/name
Rédaction de contrats
Nous utilisons Needle pour
écrire un contrat intelligent. Nous implémentons une opération d'addition
simple, le code source du contrat est le suivant, nous enregistrons le contrat
sous le nom SumMath.sim.
1 contract SumMath {
2 data {
3 A int
4 B int
5 }
6 conditions {
7
8 }
9 action {
10 var sum int
11 sum = $A + $B
12 $result = sum
13 }
14 }
Le suivant est expliqué par ligne :
- À la ligne 1, nous définissons un contrat avec le nom SumMath.
- Ligne 2, Section des données.
- Aux lignes 3-4, nous définissons deux paramètres de type entier 64 bits en
entrée,
AetB. - Ligne 6, Section conditionnelle.
- Ligne 9, Section des opérations. Nous
définissons une variable
sumpour recevoir le résultat de A+B. Nous assignons la valeur desumà$result, en tant que résultat du contrat. Bien sûr, il est possible d'assigner directement la valeur de A+B à$result, mais cela peut être montré comme un exemple.
Créer un contrat
Il existe deux façons de créer un contrat, dont la première est la suivante : Dans la première étape, nous rédigeons un fichier de paramètres de contrat au format json :
{
"ApplicationId": 31,
"Value": "contract SumMath {\n data {\n A int\n B int\n }\n conditions {\n\n }\n action {\n var sum int\n sum = $A + $B\n $result = sum\n }\n}",
"Conditions": "ContractConditions(\"@1DeveloperCondition\")"
}
où ApplicationId est l'identifiant de l'application, Value est le code
source du contrat, il est nécessaire d'échapper les caractères spéciaux,
Conditions sont les droits de modification du contrat.
Nous l'avons nommé SumMathParams.json.
La deuxième étape consiste à appeler la création d'un contrat @1NewContract:
1 >callContract @1NewContract -f=./data/SumMathParams.json
2 {
3 "block_id": 1238,
4 "hash": "f3fe7aff8a613c96299723b7e9af0682aa8cabe7becf67a485e2a77a974f58b6",
5 "penalty": 0,
6 "err": "328"
7 }
Deuxième méthode : Le fichier source du contrat enregistré est directement
transmis aux paramètres du contrat dans le format de paramètre nomParamètre +
- + "fichier", nomParamètre-fichier comme suit :
1 >callContract @1NewContract {"ApplicationId": 31, "Value-file": "SumMath.sim", "Conditions": "true"}
2 {
3 "block_id": 2055,
4 "hash": "cdf25060669cf7cba137278...26ca463fd5d458f3402a5f0137f693db",
5 "penalty": 0,
6 "err": "368"
7 }
Le suivant est expliqué par ligne :
- Ligne 1 : Appeler le contrat @1NewContract pour créer le contrat, -f utilise le fichier pour importer les paramètres du contrat
- Ligne 3 : L'identifiant de bloc généré par la transaction
- Ligne 4 : Le hachage de bloc généré par la transaction
- Ligne 5 : Si l'exécution de la transaction échoue (0 : pas de pénalité, 1 : pénalité)
- Ligne 6 : Si l'exécution de la transaction échoue, un message d'erreur est renvoyé, et si l'identifiant de bloc est renvoyé, le champ err est l'identifiant du contrat
Essayons d'appeler le contrat que nous venons de déployer.
1 >callContract @5SumMath {"A":1, "B":2}
2
3 {
4 "block_id": 1239,
5 "hash": "7fa09da0b9f65634119a910f9d91aaf4927208278efd62961499ef7e4f4c8c9c",
6 "penalty": 0,
7 "err": "3"
8 }
L'appel est terminé et le résultat est conforme aux attentes, comme expliqué ci-dessous par ligne :
- La première ligne appelle le contrat, ici nous déployons le contrat dans
l'écosystème avec l'identifiant écologique 5. Bien sûr, si l'identifiant
écologique actuel est 5, dans le même écosystème, vous pouvez également
appeler
callContract SumMath {"A":1, "B":2}de cette manière. - Ligne 3, l'identifiant de bloc généré par la transaction.
- Ligne 4, le hachage de bloc généré par la transaction.
- Ligne 5, si l'exécution de la transaction échoue (0 : pas de pénalité, 1 : pénalité).
- Ligne 6, si l'exécution de la transaction échoue, un message d'erreur est
renvoyé, et si l'identifiant de bloc est renvoyé, le champ err est le résultat
du contrat, qui est la valeur de
$result.
Outil en ligne de commande pour le développement écologique
Dans ce tutoriel, vous apprendrez comment :
Afin de comprendre plus clairement à quoi ressemble l'écosystème et les
applications IBAX et ce qu'ils font, il est préférable de comprendre où
l'écosystème et les applications devraient appartenir, et nous pouvons mieux
comprendre avec une carte mentale simple : 
Il est possible de constater que les réseaux IBAX peuvent avoir de nombreux Écosystèmes. Chaque écosystème peut avoir plusieurs applications. Chaque application possède un contrat. Tables. Chaque écosystème possède des paramètres écologiques, chaque application possède des paramètres d'application.
Étape 1 : Créer un écosystème
Nous commençons par créer un écosystème en utilisant l'outil en ligne de commande (https://github.com/IBAX-io/ibax-cli), en appelant le contrat @1NewEcosystem. Si vous souhaitez changer le nom de l'écosystème, vous pouvez appeler le contrat @1EditEcosystemName.
1 $ ibax-cli console
3 Welcome to the IBAX console!
4 To exit, press ctrl-d or type exit
5 >callContract @1NewEcosystem {"Name": "goodBoy school"}
6
7 {
8 "block_id": 1199,
9 "hash": "a1dc90c1772545c16394b9521...227676b27b145743556a8973dd",
10 "penalty": 0,
11 "err": "18"
12 }
Les éléments suivants sont expliqués par ligne :
- Ligne 1, qui lance le programme de console de ligne de commande
- Ligne 5, appelle le contrat
@1NewEcosystempour créer un écosystème avec le nom "test ecosystem" - Ligne 8, l'identifiant de bloc généré par la transaction
- Ligne 9, le hachage de bloc généré par la transaction
- Ligne 10, si l'exécution de la transaction échoue (0 : pas de pénalité, 1 : pénalité)
- Ligne 11, si l'exécution de la transaction échoue, un message d'erreur est
renvoyé, et si l'identifiant de bloc est renvoyé, le champ d'erreur est
l'identifiant de l'écosystème en tant que
18
Ensuite, nous configurons l'outil de commande config.yml, nous définissons
ecosystem sur l'ecid créé 18 et redémarrons le programme de console de ligne
de commande:
>exit
INFO[0002] Exit
$ vim data/config.yml
$ ibax-cli console
Welcome to the IBAX console!
To exit, press ctrl-d or type exit
>
Étape 2 : Créer une application
Appeler le contrat @1NewApplication pour créer l'application, qui a un
paramètre de nom d'application et un paramètre de modification
Paramètre de Permission
1 >callContract @1NewApplication {"Name": "GradesRecorder", "Conditions": "ContractConditions(\"@1DeveloperCondition\")"}
2
3 {
4 "block_id": 1246,
5 "hash": "85ab8953d26d0d1047fc610866115331babfaf88c80792d50b41826185c9f6f8",
6 "penalty": 0,
7 "err": "47"
8 }
Si vous devez modifier les autorisations de l'application, vous pouvez appeler
le contrat EditApplication.
Ce qui suit est expliqué par ligne :
- Ligne 1, appelez le contrat @1NewApplication pour créer une application, le
nom de l'application est
GradesRecorder, la permission de modification de l'application est la permission du développeur@1DeveloperCondition. - Ligne 4, l'ID de bloc généré par la transaction.
- Ligne 5, le hachage de bloc généré par la transaction.
- Ligne 6, si l'exécution de la transaction échoue (0 : pas de pénalité, 1 : pénalité).
- Ligne 7, si l'exécution de la transaction échoue, un message d'erreur est
renvoyé, et si l'ID de bloc est renvoyé, le champ err contient l'ID de
l'application qui est
47.
Écrivons un exemple simple d'une application qui suit les notes des étudiants.
Les champs de la table de données comprennent les informations sur l'étudiant,
la note grade, la classe class, les notes de matières
mathématiques, physique, littérature, le score global overall_score, la note
score, le timestamp de création (ms) created_at.
Étape 3 : Créer une table
Dans la première étape, nous rédigeons un fichier de paramètres de contrat au format json :
{
"ApplicationId": 47,
"Name": "grade_info",
"ColumnsArr": [
"student",
"grade",
"class",
"mathematics",
"physics",
"literature",
"overall_score",
"score",
"created_at"
],
"TypesArr": [
"varchar",
"number",
"number",
"number",
"number",
"number",
"number",
"varchar",
"number"
],
"InsertPerm": "ContractConditions(\"MainCondition\")",
"UpdatePerm": "ContractConditions(\"MainCondition\")",
"ReadPerm": "true",
"NewColumnPerm": "ContractConditions(\"MainCondition\")"
}
où ApplicationId est l'identifiant de l'application, Name est le nom de la
table de données créée test_table. ColumnsArr est un tableau de champs de la
table de données, TypesArr est le type des champs de la table de données,
comprenant 9 types varchar,
character, json, number, datetime, double, money, text, bytea,
le nom du champ et le type de champ sont en correspondance un à un. InsertPerm
pour la permission de nouvelle entrée dans la table de données, UpdatePerm
pour la permission de mise à jour des entrées de la table de données, ReadPerm
pour la permission de lecture des données de la table de données,
NewColumnPerm pour la permission de nouveau champ de la table de données.
En référence au
Contrôle des autorisations,
ici ContractConditions(\"MainCondition\") est disponible pour le créateur de
l'écosystème actuel.
Nous l'appelons createTable.json, puis nous appelons le contrat pour créer la
table de données @1NewTableJoint.
>callContract @1NewTableJoint -f ./createTestTable.json
Modifier les autorisations des champs de la table de données
Nous pouvons modifier les autorisations des champs de la table de données. Les
autorisations des champs de la table de données comprennent les autorisations de
lecture et de mise à jour. Les autorisations de lecture permettent d'utiliser le
filtre DBFind.Columns dans le contrat ou des interfaces telles que
list pour effectuer des
requêtes. Si aucune autorisation n'est accordée, une erreur de permission sera
signalée. La permission de mise à jour est la permission de modifier les champs
de la table de données. Nous avons défini les autorisations de lecture et de
mise à jour du champ "student" sur "false", mais bien sûr, elles peuvent être
rendues opérationnelles par certains contrats. Appelez le contrat @1EditColumn
pour modifier les autorisations des champs de la table de données.
>callContract @1EditColumn {"TableName": "grade_info", "Name": "student", "UpdatePerm": "false", "ReadPerm": "false"}
Nous pouvons créer plusieurs paramètres d'application : grade_best_type,
grade_type_a+, grade_type_a, grade_type_b+, grade_type_b,
grade_type_c, type de notation des grades.
Étape 4 : Créer les paramètres de l'application
Appelez le contrat @1NewAppParam pour créer les paramètres de l'application.
Si vous souhaitez modifier les paramètres de l'application, vous pouvez appeler
le contrat @1EditAppParam.
>callContract @1NewAppParam {"ApplicationId": 47, "Name": "grade_best_type", "Value": "A+", "Conditions": "ContractConditions(\"MainCondition\")"}
>callContract @1NewAppParam {"ApplicationId": 47, "Name": "grade_type_a+", "Value": "{\"max\": 101,\"min\": 90}", "Conditions": "ContractConditions(\"MainCondition\")"}
>callContract @1NewAppParam {"ApplicationId": 47, "Name": "grade_type_a", "Value": "{\"max\": 90,\"min\": 80}", "Conditions": "ContractConditions(\"MainCondition\")"}
>callContract @1NewAppParam {"ApplicationId": 47, "Name": "grade_type_b+", "Value": "{\"max\": 80,\"min\": 70}", "Conditions": "ContractConditions(\"MainCondition\")"}
>callContract @1NewAppParam {"ApplicationId": 47, "Name": "grade_type_b", "Value": "{\"max\": 70,\"min\": 60}", "Conditions": "ContractConditions(\"MainCondition\")"}
>callContract @1NewAppParam {"ApplicationId": 47, "Name": "grade_type_c", "Value": "{\"max\": 60,\"min\": 0}", "Conditions": "ContractConditions(\"MainCondition\")"}
Où grade_best_type est le meilleur type de notation.
grade_type_a+ est la condition déclenchée par la notation A+, lorsque le
score est supérieur ou égal à 90 et inférieur à 101, la notation est A+, les
autres paramètres sont similaires.
Étape 5 : Créer un contrat et le déployer.
Nous créons un contrat pour enregistrer les informations de notes des étudiants et leur note finale pour chaque matière, et nous saisissons la classe et la note de l'étudiant pour chaque matière lors de la saisie des informations.
En fonction des notes saisies pour chaque matière, nous effectuons un calcul de
moyenne pour obtenir la note globale overallScore et la note finale score.
Lorsque le contrat est appelé, il créera un enregistrement dans la table de
données que nous venons de créer grade_info.
D'abord, nous écrivons un contrat et le nommons NewRecord.sim
1 contract NewRecord {
2 data {
3 Student string
4 Grade int
5 Class int
6 Mathematics int
7 Physics int
8 Literature int
9 }
10 func getScore(a b c int) map{
11 var m map
12 var overallScore int
13 overallScore = (a+b+c) / 3
14 m["overallScore"] = overallScore
15 if overallScore >= $gradeTypeABest["min"] && overallScore < $gradeTypeABest["max"] {
16 m["score"] = "A+"
17 }elif overallScore >= $gradeTypeA["min"] && overallScore < $gradeTypeA["max"] {
18 m["score"] = "A"
19 }elif overallScore >= $gradeTypeBBest["min"] && overallScore < $gradeTypeBBest["max"] {
20 m["score"] = "B+"
21 }elif overallScore >= $gradeTypeB["min"] && overallScore < $gradeTypeB["max"] {
22 m["score"] = "B"
23 }elif overallScore >= $gradeTypeC["min"] && overallScore < $gradeTypeC["max"]{
24 m["score"] = "C"
25 }else{
26 m["score"] = "Notset"
27 }
28 return m
29 }
30 func safeJsonDecode(m string) map {
31 var res map
32 if Size(m) > 0 {
33 res = JSONDecode(m)
34 }
35 return res
36 }
37
38 conditions {
39 if Size($Student) == 0 {
40 warning "Student Can not be empty"
41 }
42 if $Class <= 0{
43 warning "Class cannot be less than or equal to zero"
44 }
45 if $Grade <= 0{
46 warning "Grade cannot be less than or equal to zero"
47 }
48 if $Mathematics < 0 {
49 warning "Mathematics cannot be less than zero"
50 }
51 if $Physics < 0 {
52 warning "Physics cannot be less than zero"
53 }
54 if $Literature < 0 {
55 warning "Literature cannot be less than zero"
56 }
57 if $Mathematics > 100 || $Physics > 100 || $Literature > 100{
58 warning "Score cannot exceed 100"
59 }
60 var app map
61 app = DBFind("@1applications").Columns("id,ecosystem").Where({"ecosystem": 18,"name":"GradesRecorder","deleted":0}).Row()
62 if !app {
63 warning LangRes("@1app_not_found")
64 }
65
66 var app_id int
67 app_id = Int(app["id"])
68 $eId = Int(app["ecosystem"])
69 $gradeBestType = AppParam(app_id, "grade_best_type", $eId)
70 $gradeTypeABest = safeJsonDecode(AppParam(app_id, "grade_type_a+", $eId))
71 $gradeTypeA = safeJsonDecode(AppParam(app_id, "grade_type_a", $eId))
72 $gradeTypeBBest = safeJsonDecode(AppParam(app_id, "grade_type_b+", $eId))
73 $gradeTypeB = safeJsonDecode(AppParam(app_id, "grade_type_b", $eId))
74 $gradeTypeC = safeJsonDecode(AppParam(app_id, "grade_type_c", $eId))
75 }
76 action {
77 var m map
78 m = getScore($Mathematics,$Physics,$Literature)
79 var in map
80 in["student"] = $Student
81 in["class"] = $Class
82 in["grade"] = $Grade
83 in["mathematics"] = $Mathematics
84 in["physics"] = $Physics
85 in["literature"] = $Literature
86 in["overall_score"] = m["overallScore"]
87 in["score"] = m["score"]
88 in["created_at"] = $time
89 DBInsert("@"+ Str($eId)+"grade_info", in)
90 }
91 }
Ce qui suit est expliqué par ligne:
- Ligne 2, section des données définit les
paramètres d'entrée
Studentnom de l'étudiant,Gradeclasse,Classclasse,Mathematicsscore en mathématiques,Physicsscore en physique,Literaturescore en littérature. - Ligne 10, la fonction getScore, produit un score composite et une note finale basée sur le score de chaque matière.
- Ligne 30, la fonction safeJsonDecode, décode la chaîne JSON et la convertit en map.
- Ligne 38, section conditionnelle.
- Ligne 39, section des opérations.
Comme vous pouvez le voir, lorsque le contrat est appelé, il passe d'abord par
la partie conditionnelle, vérifiant que les paramètres d'entrée du contrat sont
valides, tels que le nom de l'étudiant if Size($Student) == 0 { est vide
(ligne 39), et s'il l'est, un message d'erreur est renvoyé
"L'étudiant ne peut pas être vide" (ligne 30). Après avoir vérifié tous les
paramètres d'entrée, à la ligne 61, utilisez
DBFind pour récupérer les informations de la base
de données pour l'application avec l'ecid 18 et le nom de l'application
GradesRecorder et les informations de l'application avec deleted=0 ne sont
pas supprimées.
Aux lignes 69-74, utilisez AppParam pour
récupérer les paramètres de l'application, par exemple
$gradeBestType = AppParam(app_id, "grade_best_type", $ eId) (ligne 69).
Si le paramètre de l'application est stocké au format json, tel que
grade_type_a, vous pouvez vous référer à
$gradeTypeABest = safeJsonDecode(AppParam(app_id, "grade_type_a+", $eId)), qui
obtiendra le paramètre de l'application par la fonction safeJsonDecode au format
map.
Ensuite, passez à la partie opérationnelle, appelez la fonction getScore pour
obtenir le score composite résultant et la note finale (ligne 10), utilisez une
map pour stocker, ligne 79, définissez une map pour stocker les informations de
réussite de l'étudiant, et DBInsert Insérez les
données dans la table de données @18grade_info.
Il existe deux façons de créer un contrat, la première consiste à: Tout d'abord, nous écrivons un fichier de paramètres de contrat au format json:
{
"ApplicationId": 47,
"Value": "contract NewRecord {\n data {\n Student string\n Grade int\n Class int\n Mathematics int\n Physics int\n Literature int\n }\n func getScore(a b c int) map{\n var m map\n var overallScore int\n overallScore = (a+b+c) / 3\n m[\"overallScore\"] = overallScore\n if overallScore >= $gradeTypeABest[\"min\"] && overallScore < $gradeTypeABest[\"max\"] {\n m[\"score\"] = \"A+\"\n }elif overallScore >= $gradeTypeA[\"min\"] && overallScore < $gradeTypeA[\"max\"] {\n m[\"score\"] = \"A\"\n }elif overallScore >= $gradeTypeBBest[\"min\"] && overallScore < $gradeTypeBBest[\"max\"] {\n m[\"score\"] = \"B+\"\n }elif overallScore >= $gradeTypeB[\"min\"] && overallScore < $gradeTypeB[\"max\"] {\n m[\"score\"] = \"B\"\n }elif overallScore >= $gradeTypeC[\"min\"] && overallScore < $gradeTypeC[\"max\"]{\n m[\"score\"] = \"C\"\n }else{\n m[\"score\"] = \"Notset\"\n }\n return m\n }\n func safeJsonDecode(m string) map {\n var res map\n if Size(m) > 0 {\n res = JSONDecode(m)\n }\n return res\n }\n\n conditions {\n if Size($Student) == 0 {\n warning \"Student Can not be empty\"\n }\n if $Class <= 0{\n warning \"Class cannot be less than or equal to zero\"\n }\n if $Grade <= 0{\n warning \"Grade cannot be less than or equal to zero\"\n }\n if $Mathematics < 0 {\n warning \"Mathematics cannot be less than zero\"\n }\n if $Physics < 0 {\n warning \"Physics cannot be less than zero\"\n }\n if $Literature < 0 {\n warning \"Literature cannot be less than zero\"\n }\n if $Mathematics > 100 || $Physics > 100 || $Literature > 100{\n warning \"Score cannot exceed 100\"\n }\n var app map\n app = DBFind(\"@1applications\").Columns(\"id,ecosystem\").Where({\"ecosystem\": 18,\"name\":\"GradesRecorder\",\"deleted\":0}).Row()\n if !app {\n warning LangRes(\"@1app_not_found\")\n }\n\n var app_id int\n app_id = Int(app[\"id\"])\n $eId = Int(app[\"ecosystem\"])\n $gradeBestType = AppParam(app_id, \"grade_best_type\", $eId)\n $gradeTypeABest = safeJsonDecode(AppParam(app_id, \"grade_type_a+\", $eId))\n $gradeTypeA = safeJsonDecode(AppParam(app_id, \"grade_type_a\", $eId))\n $gradeTypeBBest = safeJsonDecode(AppParam(app_id, \"grade_type_b+\", $eId))\n $gradeTypeB = safeJsonDecode(AppParam(app_id, \"grade_type_b\", $eId))\n $gradeTypeC = safeJsonDecode(AppParam(app_id, \"grade_type_c\", $eId))\n }\n action {\n var m map \n m = getScore($Mathematics,$Physics,$Literature)\n var in map\n in[\"student\"] = $Student\n in[\"class\"] = $Class\n in[\"grade\"] = $Grade\n in[\"mathematics\"] = $Mathematics\n in[\"physics\"] = $Physics \n in[\"literature\"] = $Literature \n in[\"overall_score\"] = m[\"overallScore\"]\n in[\"score\"] = m[\"score\"]\n in[\"created_at\"] = $time\n DBInsert(\"@\"+ Str($eId)+\"grade_info\", in)\n }\n}",
"Conditions": "ContractConditions(\"@1DeveloperCondition\")"
}
Où ApplicationId est l'identifiant de l'application, qui doit être échappé
pour les caractères spéciaux, et Conditions est la permission de modification
du contrat.
Code source du contrat Value, que nous enregistrons sous le nom
NewRecordParams.json.
Après avoir rédigé le contrat, nous devons le déployer en appelant
CreateContract@1NewContract.
1 >>callContract @1NewContract -f=./data/NewRecordParams.json
2 {
3 "block_id": 1262,
4 "hash": "d896f12f685835f6cf71705e1ba...4d8bcc0a1406f7b0b6482b2d230fc",
5 "penalty": 0,
6 "err": "348"
7 }
La ligne suivante est expliquée par ligne :
- Ligne 1 : appeler le contrat
@1NewContractpour créer le contrat, -f utilise le fichier pour importer le fichierNewRecord.jsonnouvellement créé en tant que paramètre du contrat. - Ligne 3 : l'identifiant de bloc généré par la transaction.
- Ligne 4 : le hachage de bloc généré par la transaction.
- Ligne 5 : si l'exécution de la transaction échoue (0 : pas de pénalité, 1 : pénalité).
- Ligne 6 : si l'exécution de la transaction échoue, un message d'erreur est
renvoyé, et si l'identifiant de bloc est renvoyé, le champ d'erreur contient
l'identifiant du contrat qui est
348.
Deuxième méthode : Le fichier source du contrat enregistré est directement
transmis aux paramètres du contrat dans le format de paramètre nomParamètre +
- + "fichier", nomParamètre-fichier comme suit :
callContract @1NewContract {"ApplicationId": 47, "Value-file": "NewRecord.sim", "Conditions": "ContractConditions(\"@1DeveloperCondition\ ")"}
Essayons d'appeler le contrat que nous venons de créer.
1 >callContract @18NewRecord {"Student": "tom", "Grade": 1, "Class": 1, "Mathematics": 18, "Physics": 57, "Literature": 93}
2
3 {
4 "block_id": 1263,
5 "hash": "1b964a47fe6c5fd43ea55a752d01edb5ad576432fd6f63315344d87999a0473d",
6 "penalty": 0,
7 "err": ""
8 }
The call is complete, and then we check to see if the data table has saved a record
>getList @18grade_info
{
"count": 1,
"list": [
{
"class": "1",
"created_at": "1683698914109",
"grade": "1",
"id": "9",
"literature": "93",
"mathematics": "18",
"overall_score": "56",
"physics": "57",
"score": "C",
"student": "tom"
}
]
}
Vous pouvez voir qu'il y a déjà un enregistrement dans la table de données,
student tom avec une note globale de 56 et une note de C.
L'exemple ci-dessus est uniquement à des fins d'étude et de recherche, vous devez modifier les paramètres pertinents en fonction de la situation réelle, tels que la permission d'écriture dans la table de données, la permission de modification de contrat, etc.
Par exemple, si nous voulons spécifier qu'une seule personne peut appeler ce
nouveau contrat et que personne d'autre ne peut l'appeler, nous pouvons définir
un paramètre écologique new_record_account.
Étape 6 : Créer des paramètres écologiques
Appeler le contrat @1NewParameter créera l'éco-paramètre new_record_account
dans la table @1parameters. Si vous avez besoin de modifier l'éco-paramètre,
vous pouvez appeler @1EditParameter.
>callContract @1NewParameter {"Name": "new_record_account", "Value": "6667782293976713160", "Conditions": "ContractConditions(\"MainCondition\")"}
{
"block_id": 1416,
"hash": "12fc87ce6a70e2fc993ab9ffe623311f1c50edd1157595ce6183c38c93960cae",
"penalty": 0,
"err": "273"
}
Nous créons un paramètre d'écosystème appelé new_record_account, nous
définissons la valeur sur la cléId 6667782293976713160, nous modifions les
permissions pour ContractConditions("MainCondition"), ce qui signifie que le
créateur écologique actuel peut modifier. Lorsque la transaction est exécutée
avec succès, l'identifiant du paramètre écologique dans le champ "err" est
273.
Étape 7 : ajouter la localisation
Vous pouvez appeler le contrat @1NewLangJoint pour créer le paramètre de
localisation account_not_access, qui créera le paramètre dans la table
@1languages, et vous pouvez modifier le paramètre de localisation via
@1EditLangJoint.
callContract @1NewLangJoint {"Name": "account_not_access", "LocaleArr": ["en", "ja"], "ValueArr": ["Sorry, you do not have access to this action", "申し訳ありませんが、このアクションにアクセスする権限がありません"]}
Étape 8 Modifier le contrat
Ensuite, nous devons modifier la section conditions du code source du contrat
en ajoutant le code suivant aux conditions.
conditions {
if EcosysParam("new_record_account") != $key_id {
warning LangRes("account_not_access")
}
}
Appeler pour modifier le contrat @1EditContract, où Id est l'identifiant du
contrat, Value est le code source du contrat.
>callContract @1EditContract {"Id": 348, "Value": "contract NewRecord {\n data {\n Student string\n Grade int\n Class int\n Mathematics int\n Physics int\n Literature int\n }\n func getScore(a b c int) map{\n var m map\n var overallScore int\n overallScore = (a+b+c) / 3\n m[\"overallScore\"] = overallScore\n if overallScore >= $gradeTypeABest[\"min\"] && overallScore < $gradeTypeABest[\"max\"] {\n m[\"score\"] = \"A+\"\n }elif overallScore >= $gradeTypeA[\"min\"] && overallScore < $gradeTypeA[\"max\"] {\n m[\"score\"] = \"A\"\n }elif overallScore >= $gradeTypeBBest[\"min\"] && overallScore < $gradeTypeBBest[\"max\"] {\n m[\"score\"] = \"B+\"\n }elif overallScore >= $gradeTypeB[\"min\"] && overallScore < $gradeTypeB[\"max\"] {\n m[\"score\"] = \"B\"\n }elif overallScore >= $gradeTypeC[\"min\"] && overallScore < $gradeTypeC[\"max\"]{\n m[\"score\"] = \"C\"\n }else{\n m[\"score\"] = \"Notset\"\n }\n return m\n }\n func safeJsonDecode(m string) map {\n var res map\n if Size(m) > 0 {\n res = JSONDecode(m)\n }\n return res\n }\n\n conditions {\n if EcosysParam(\"new_record_account\") != $key_id {\n warning LangRes(\"account_not_access\")\n }\n if Size($Student) == 0 {\n warning \"Student Can not be empty\"\n }\n if $Class <= 0{\n warning \"Class cannot be less than or equal to zero\"\n }\n if $Grade <= 0{\n warning \"Grade cannot be less than or equal to zero\"\n }\n if $Mathematics < 0 {\n warning \"Mathematics cannot be less than zero\"\n }\n if $Physics < 0 {\n warning \"Physics cannot be less than zero\"\n }\n if $Literature < 0 {\n warning \"Literature cannot be less than zero\"\n }\n if $Mathematics > 100 || $Physics > 100 || $Literature > 100{\n warning \"Score cannot exceed 100\"\n }\n var app map\n app = DBFind(\"@1applications\").Columns(\"id,ecosystem\").Where({\"ecosystem\": 18,\"name\":\"GradesRecorder\",\"deleted\":0}).Row()\n if !app {\n warning LangRes(\"@1app_not_found\")\n }\n\n var app_id int\n app_id = Int(app[\"id\"])\n $eId = Int(app[\"ecosystem\"])\n $gradeBestType = AppParam(app_id, \"grade_best_type\", $eId)\n $gradeTypeABest = safeJsonDecode(AppParam(app_id, \"grade_type_a+\", $eId))\n $gradeTypeA = safeJsonDecode(AppParam(app_id, \"grade_type_a\", $eId))\n $gradeTypeBBest = safeJsonDecode(AppParam(app_id, \"grade_type_b+\", $eId))\n $gradeTypeB = safeJsonDecode(AppParam(app_id, \"grade_type_b\", $eId))\n $gradeTypeC = safeJsonDecode(AppParam(app_id, \"grade_type_c\", $eId))\n }\n action {\n var m map \n m = getScore($Mathematics,$Physics,$Literature)\n var in map\n in[\"student\"] = $Student\n in[\"class\"] = $Class\n in[\"grade\"] = $Grade\n in[\"mathematics\"] = $Mathematics\n in[\"physics\"] = $Physics \n in[\"literature\"] = $Literature \n in[\"overall_score\"] = m[\"overallScore\"]\n in[\"score\"] = m[\"score\"]\n in[\"created_at\"] = $time\n DBInsert(\"@\"+ Str($eId)+\"grade_info\", in)\n }\n}"}
Étape 9 Modifier les autorisations de la table de données
Ici, nous devons modifier l'autorisation d'insertion de la table de données,
l'autorisation d'origine ContractConditions("MainCondition") pour l'écréateur,
et le paramètre de contrat new_record_account n'est pas l'écréateur.
Donc, il suffit de modifier ContractConditions("MainCondition") pour spécifier
que le contrat peut opérer sur ContractAccess("@18NewRecord").
Appelez le contrat @1EditTable pour modifier les autorisations de la table de
données.
>callContract @1EditTable {"Name": "@18grade_info", "InsertPerm": "ContractAccess(\"@18NewRecord\")", "UpdatePerm": "ContractConditions(\"MainCondition\")", "ReadPerm": "true", "NewColumnPerm": "ContractConditions(\"MainCondition\")"}
Ensuite, appelez le contrat que vous venez de modifier et créez un nouvel enregistrement.
1 >callContract @18NewRecord {"Student": "tom", "Grade": 1, "Class": 1, "Mathematics": 18, "Physics": 57, "Literature": 93}
2
3 {
4 "block_id": 1435,
5 "hash": "7d4b06d3738133f9c2ec775935478cd2d6c20fd04eca275769afd0f8e6a4f687",
6 "penalty": 1,
7 "err": "{\"type\":\"warning\",\"error\":\"Sorry, you do not have access to this action\"}"
8 }
Vous pouvez voir que le paramètre de localisation que nous venons de définir,
account_not_access, fonctionne.
Nous avons constaté que l'erreur de permission est signalée, l'utilisateur
actuel n'a pas l'autorisation d'effectuer des opérations. Nous passons au compte
avec l'identifiant de clé 6667782293976713160 et nous pouvons obtenir les
informations de l'utilisateur actuel à l'aide de l'outil en ligne de commande
account info.
Configurez le fichier de configuration de l'outil en ligne de commande
config.yml et passez au compte avec l'identifiant de clé 6667782293976713160.
Une fois la configuration terminée, appelez à nouveau le contrat.
>callContract @18NewRecord {"Student": "tini", "Grade": 1, "Class": 3, "Mathematics": 69, "Physics": 89, "Literature": 98}
{
"block_id": 1436,
"hash": "93327dafb7bae9f9f66718eb87020a7bca4c00060f4bd0a243b49eea304c52e6",
"penalty": 0,
"err": ""
}
L'appel est terminé, interrogeant la table de données via
getList @18grade_info, et le résultat est conforme aux attentes.
Nous espérons que cet article vous a aidé à en savoir plus sur le fonctionnement
du réseau IBAX et sur la façon d'écrire un code Needle clair et sécurisé.
Déployer une application à l'aide d'outils en ligne de commande
Dans ce tutoriel, vous apprendrez comment :
Avant de commencer ce tutoriel, vous devez avoir votre propre application et connaître le concept d'écosystème et d'application. Vous pouvez vous référer au Guide de démarrage.
Nous importerons l'application sur la blockchain IBAX via l'outil en ligne de commande ibax-cli. Exporter une application.
Exporter l'application
Appeler account info pour interroger les informations du compte actuel, ici le
login ecid est 9, appeler la commande getList pour interroger les
applications associées à l'ecid actuel.
$ ibax-cli console
Welcome to the IBAX console!
To exit, press ctrl-d or type exit
>account info
{
"public_key": "04d11ea197fe23152562c6f54c4...889c074dfd9080099982d8b2d4d100315e1cebc7",
"ecosystem_id": 9,
"key_id": 6660819...78795186,
"account": "0666-0819-...-7879-5186"
}
>getList @1applications -w={"ecosystem": 9}
{
"count": 6,
"list": [
{
"conditions": "true",
"deleted": "0",
"ecosystem": "9",
"id": "36",
"name": "testapp",
"uuid": "00000000-0000-0000-0000-000000000000"
}
...
]
}
Nous pouvons voir que l'écosystème actuel compte 6 applications. Nous utilisons
la commande export pour exporter l'application avec l'id de 36.
>export 36 -f=./data.json
{
"name": "./data.json",
"type": "application/json",
"value": ""
}
Le paramètre -f ici enregistre l'application exportée dans le fichier
data.json dans le répertoire actuel. Si aucun paramètre -f n'est spécifié, les
données de l'application seront affichées dans le terminal de commande.
La commande export encapsule les étapes pour exporter une application. Vous
pouvez utiliser la commande ci-dessus pour exporter une application, ou suivre
les étapes suivantes, comme suit :
Appeler le contrat @1ExportNewApp pour exporter une nouvelle application
générera un enregistrement dans la table 1_buffer_data pour l'application
exportée.
>callContract @1ExportNewApp {"ApplicationId": 36}
Appelez le contrat @1Export pour exporter l'application, recherchez
l'application sélectionnée dans la table 1_buffer_data, et exportez toutes les
ressources de l'application vers la chaîne JSON générée.
La chaîne JSON générée sera écrite dans la table 1_binaries de l'écosystème
actuel.
>callContract @1Export
Interrogez les données dans la table 1_binaries avec la commande getList.
>getList @1binaries -w={"name": "export", "account": "0666-0819-...-7879-5186", "ecosystem": 9, "app_id": 36} -l=1 -c="id,hash"
{
"count": 1,
"list": [
{
"hash": "8542cb57b77e0ae2c...92c3e05dbbe35ab646789be5b8ba8",
"id": "14"
}
]
}
Obtenez l'identifiant binaire et le hachage.
Appelez la commande binaryVerify pour exporter le fichier binaire.
>binaryVerify 14 8542cb57b77e0ae2c...92c3e05dbbe35ab646789be5b8ba8 -f=./data.json
{
"name": "./data.json",
"type": "application/json",
"value": ""
}
Importer l'application
Utilisez la commande import pour importer une application, avec le paramètre
-f pour spécifier le fichier d'application à importer.
$ ibax-cli console
Welcome to the IBAX console!
To exit, press ctrl-d or type exit
>import -f . /data.json
The import command encapsulates the steps to import an application, you can
use the above command to import an application
Or use the following steps, which, for ease of study and research, are as follows:
- Étape 1 : Appeler le contrat
@1ImportUploadpour importer une nouvelle application générera un enregistrement dans la table1_buffer_datapour l'application exportée.@1ImportUploadLe paramètre du contratDataestfiletype. Il contient les mots-clésNamepour le nom du fichier (chaîne de caractères),MimeTypepour le type de fichier (chaîne de caractères),Bodypour le contenu du fichier ([]byte). Vous devez encoder en base64 les données du fichier de l'application et les passer dansBody, vous pouvez utiliser la commandebase64Encodepour les encoder en base64.
>base64Encode -f=./data.json
Encode:ewoJIm5hbWUiOiAid...CQkJIlR5cGUiOiAiY29udHJhY3RzIiwKCQkJIk5hbWUiOiAiSGVsbG9Xb3JsZCIsCgkJCSJWYWx1ZSI6...
>callContract @1ImportUpload {"Data": {"Name": "filename", "MimeType": "mimeType", "Body": "ewoJIm5hbWUiOiAid...CQkJIlR5cGUiOiAiY29udHJhY3RzIiwKCQkJIk5hbWUiOiAiSGVsbG9Xb3JsZCIsCgkJCSJWYWx1ZSI6..."}}
- Étape 2 : Après que l'appel est terminé, utilisez la commande
getListpour interroger les données dans la table1_buffer_data.
>getList @1buffer_data -w={"key": "import", "account": "0666-0819-xxxx-7879-5186", "ecosystem": 19} -l=1 -c=value->'data'
{
"count": 1,
"list": [
{
"id": "22",
"value.data": "[{"Data": "[a,b]"}, {"Data": "[c,d]"}]"
}
]
}
- Étape 3 : Assemblez les données de value.data->Data dans un tableau
unidimensionnel, [a,b,c,d]. Ensuite, créez un fichier de paramètres de contrat
importParams.json, avec le contenu suivant :
{ "Data": "[a,b,c,d]" }
- Étape 4 : Appelez le contrat
@1Importpour importer les données de l'application.
>callContract @1Import -f=./importParams.json
Configuration écologique à l'aide d'un outil en ligne de commande
Dans ce tutoriel, vous apprendrez comment :
Avant de commencer ce tutoriel, vous devez avoir votre propre application et connaître le concept d'écosystème et d'application. Vous pouvez vous référer au Guide de démarrage.
Nous allons effectuer la configuration écologique sur la blockchain IBAX via l'outil en ligne de commande ibax-cli.
Postuler pour rejoindre l'écosystème
Nous pouvons appeler le contrat @1MembershipRequest pour demander à rejoindre
l'écosystème.
L'exemple suivant:
>callContract @1MembershipRequest {"EcosystemId": 19}
Demande de rejoindre l'écosystème avec l'identifiant écologique 19, le contrat
@1MembershipRequest impose une restriction sur l'appel de l'écosystème, seul
l'écosystème de base peut être appelé.
Lorsque la demande est acceptée, le gestionnaire de l'écosystème cible recevra une demande et elle ne sera considérée comme faisant partie de l'écosystème cible que lorsque la demande sera approuvée par le gestionnaire de l'écosystème.
Bien sûr, si l'écosystème cible est public, vous pouvez le rejoindre directement.
Ajouter des membres de l'écosystème
Lorsque l'écosystème vient d'être créé, le seul membre de l'écosystème est le
créateur de l'écosystème. Lorsque vous souhaitez inviter d'autres membres à
rejoindre, vous devez connaître la clé publique de la personne invitée, puis
appeler le contrat @1MembershipAdd pour ajouter des membres.
>callContract @1MembershipAdd {"Keys": "04f2c1780ca0aa0f343d0e541c77811...3b0d5bf3a9903253aad6e78c966b5f91ffb32703884020"}
Si l'écosystème est public et permet à n'importe qui de rejoindre, vous pouvez
définir le paramètre de l'écosystème free_membership = 1, qui n'est pas public
par défaut.
Une fois configuré, vous n'avez pas besoin d'être approuvé pour rejoindre votre écosystème.
>callContract @1NewParameter {"Name": "free_membership", "Value": "1", "Conditions": "ContractConditions(\"MainCondition\")"}
Si vous ne définissez pas le paramètre free_membership, lorsque d'autres
membres demandent à rejoindre votre écosystème, vous recevrez une notification
de demande.
Appelez l'application d'approbation du contrat @1MembershipDecide, les
paramètres du contrat NotificId sont l'identifiant de la notification,
'Accept' est la marque de résolution, la marque de résolution 1 est acceptée.
>callContract @1MembershipDecide {"NotificId": 6, "Accept": 1}
Blocage des comptes
Appeler le contrat @1DeleteMember pour geler le compte, notez que cette
opération ne peut pas être restaurée.
>callContract @1DeleteMember {"MemberAccount": "1539-2715-xxxx-1679-5385"}
Gestion des rôles
- Création d'un nouveau rôle
- Ajouter un membre au rôle
- Supprimer un membre du rôle
- Modifier le gestionnaire du rôle
- Supprimer le rôle
Création d'un nouveau rôle
Appeler le contrat @1RolesCreate pour créer un nouveau rôle, nom du rôle
student, type 2 (1 - Assignable 2 - Élu par vote 3 - Système).
>callContract @1RolesCreate {"Name": "student", "Type": 2}
{
"block_id": 1685,
"hash": "5321f2231a...d0d80158b62766395f14d0ff7",
"penalty": 0,
"err": "21"
}
Le résultat de retour contient l'identifiant de rôle 21.
Ajout de membres de rôle
Il existe deux méthodes, la première méthode consiste à ce que le membre de
l'écosystème initie la demande d'application en appelant le contrat
@1RolesRequest pour demander à être ajouté en tant que membre du rôle, où
Rid est l'identifiant du rôle.
>callContract @1RolesRequest {"Rid": 21}
Dans la deuxième méthode, le gestionnaire de rôles attribue des membres de rôle,
et le gestionnaire de rôles appelle le contrat @1RolesAssign pour ajouter des
membres au rôle.
>callContract @1RolesAssign {"MemberAccount": "0666-7782-xxxx-7671- 3160", "Rid": 21}
Supprimer les membres du rôle
Tout d'abord, nous voyons quels membres un rôle possède, que nous pouvons interroger via getList, comme suit:
>getList @1roles_participants -w={"ecosystem": 18, "role->id": "21", "deleted": 0}
{
"count": 3,
"list": [
{
"appointed": "{\"account\": \"1273-2644-xxxx-5846-6598\", \"image_id\": \"0\", \"member_name\": \"founder\"}",
"date_created": "1684916023",
"date_deleted": "0",
"deleted": "0",
"ecosystem": "18",
"id": "21",
"member": "{\"account\": \"1273-2644-xxxx-5846-6598\", \"image_id\": \"0\", \"member_name\": \"founder\"}",
"role": "{\"id\": \"20\", \"name\": \"teacher\", \"type\": \"1\", \"image_id\": \"0\"}"
}
...
]
}
Où la condition where ecosystem spécifie l'écosystème, role->id spécifie
l'identifiant du rôle et deleted: 0 spécifie non supprimé.
Nous pouvons voir que nous avons 3 lignes, si nous voulons supprimer le rôle
avec le membre 1273-2644-xxxx-5846-6598, c'est-à-dire le rôle avec l'id de
21.
Les administrateurs peuvent appeler le contrat @1RolesUnassign pour supprimer
les membres du rôle, comme suit:
>callContract @1RolesUnassign {"RowId": 21}
Modifier le gestionnaire de rôles
Regardons les rôles écologiques actuels :
>getList @1roles -w={"ecosystem": 18}
{
"count": 5,
"list": [
{
"company_id": "0",
"creator": "{\"account\": \"1273-2644-xxxx-5846-6598\", \"image_id\": \"0\", \"member_name\": \"founder\"}",
"date_created": "1684910917",
"date_deleted": "0",
"default_page": "",
"deleted": "0",
"ecosystem": "18",
"id": "20",
"image_id": "0",
"role_name": "teacher",
"role_type": "1",
"roles_access": "[]"
}
...
]
}
où roles_access est le rôle administratif pour le rôle actuel, qui est un
tableau et peut en avoir plusieurs.
Nous ajoutons un rôle administratif au rôle teacher en appelant le contrat
@1RolesAccessManager, où les paramètres du contrat sont Action l'opérateur
administratif (clean, remove, add), Rid l'ID du rôle à gérer,
ManagerRid l'ID du gestionnaire de rôle.
>callContract @1RolesAccessManager {"Action": "add", "Rid": 20, "ManagerRid": 13}
{
"block_id": 1745,
"hash": "e2eb8ff0dc309ec7652db...bbbe58bca4ca574804e46c2f63653eb73104",
"penalty": 0,
"err": ""
}
Supprimer le rôle
Nous pouvons appeler le contrat @1RolesDelete pour supprimer des rôles, où les
paramètres du contrat Rid sont l'ID du rôle à gérer et Ops est l'opérateur
(D pour supprimer, R pour restaurer).
>callContract @1RolesDelete {"Rid": 24, "Ops": "D"}
{
"block_id": 1785,
"hash": "1ebf99a04f504fc3d2...4ecfbdfc419bf3dbf39df0013dca913f844",
"penalty": 0,
"err": ""
}
Émission de jeton
Créer un écosystème
Créez un écosystème, appelez le contrat @1NewEcosystem.
>callContract @1NewEcosystem {"Name": "Test Ecosystem"}
{
"block_id": 1787,
"hash": "384f35ef93243c9dd4f53b9298873b356b25b31cf7c6a6be7600ee7694d77006",
"penalty": 0,
"err": "21"
}
Ensuite, nous modifions la configuration de l'outil en ligne de commande pour se connecter à cet écosystème nouvellement créé : "21".
Installation des applications de base
Appelez le contrat pour installer l'application de base, comme suit :
1 >callContract @1PlatformAppsInstall
2 >callContract @1RolesInstall
3 >callContract @1AppInstall {"ApplicationId": 5}
4 >callContract @1AppInstall {"ApplicationId": 6}
Ligne 1, installez l'application de plateforme ;
Ligne 2, installez le rôle par défaut ;
Ligne 3-4, installez l'application de configuration écologique et d'émission de
jetons, où l'ID de l'application 5,6 peut être consulté via getList comme suit
:
>getList @1applications -w={"ecosystem": 1, "$or": [{"name": "Token emission"},{"name": "Ecosystems catalog"}]} -c="name,ecosystem"
{
"count": 2,
"list": [
{
"ecosystem": "1",
"id": "5",
"name": "Token emission"
},
{
"ecosystem": "1",
"id": "6",
"name": "Ecosystems catalog"
}
]
}
Émission de jetons
Parce qu'il s'agit d'un nouvel écosystème, vous devez configurer l'émission de
jetons, appelez le contrat @1TeSettings pour spécifier les rôles pouvant
émettre des jetons.
>callContract @1TeSettings {"RoleDeveloper": 30}
Où RoleDeveloper est l'identifiant actuel du rôle écologique, qui peut être
obtenu via la table de données @1roles.
Émission de jetons Appeler le contrat @1NewToken pour émettre des jetons.
>callContract @1NewToken {"Symbol": "TEST", "Name": "TEST Coin", "Amount": "10000000000000000" ,"Digits": "12"}
Où les paramètres du contrat Symbol sont le symbole du jeton, Name est le
nom du jeton, Amount est le montant total et Digits est la précision.
Émission de jetons
>callContract @1TeEmission {"Amount": 1000000000000}
Détruire les jetons
>callContract @1TeBurn {"Amount": 1000000000000}
Incrément de jeton par défaut et destruction de jeton sont autorisés, vous
pouvez les désactiver en utilisant @1TeChange, où TypeChange est le type
(emission pour l'incrément, withdraw pour la destruction).
Value est l'état activé/désactivé (1 activé, 2 désactivé), par exemple:
Ajouts fermés.
Note: Ne peut pas être activé après la fermeture.
>callContract @1TeChange {"TypeChange": "emission", "Value": 2}
Désactiver la destruction, si vous souhaitez réactiver la destruction, il
suffit de définir la valeur de Value sur 1.
>callContract @1TeChange {"TypeChange": "withdraw", "Value": 2}
Déduction de l'écosystème
Avant de mettre en place des déductions écologiques, vous devez comprendre le modèle de frais IBAX, qui peut être trouvé dans le livre blanc.
Nous commençons par définir l'adresse du portefeuille écologique, appelons le
contrat @1EditParameter et modifions les paramètres écologiques.
>callContract @1EditParameter {"Id": 334, "Value": "1273-2644-xxxx-5846-6598"}
Où Id est l'identifiant du paramètre ecosystem_wallet de l'ecowallet, qui
peut être interrogé comme suit :
>getList @1parameters -w={"ecosystem": 22, "name": "ecosystem_wallet"}
La valeur Value est l'adresse de l'ecowallet qui sera liée, et le contrat
génère les frais de gaz, qui sont payés par cette adresse. L'adresse doit avoir
suffisamment de jetons dans l'écosystème actuel et doit être approuvée par
l'adresse liée avant que la modification ne soit réussie.
Appeler le contrat @1EcoFeeModeManage pour configurer la déduction
multi-écologique, comme suit :
>callContract @1EcoFeeModeManage {"FollowFuel": 0.01, "CombustionFlag": 1, "VmCostFlag": 2, "VmCostConversionRate": 100, "StorageConversionRate": 100, "StorageFlag": 2, "ExpediteFlag": 1}
Où les champs de paramètres du contrat sont définis comme suit :
- Le paramètre
FollowFuelest un multiple du taux d'éco-suivi 1. CombustionFlagindique s'il faut activer la combustion des frais de gaz d'éco-échange, 1 - non, 2 - oui.CombustionPercentest le pourcentage de combustion, uniquement valable lorsque la combustion des frais de gaz est activée, prend des valeurs de 1 à 100, 0 lorsque ce n'est pas activé.VmCostFlagest le drapeau des coûts de VM, définissant le paiement direct ou par procuration, 1 - paiement direct, 2 - paiement par procuration.StorageFlagest le drapeau des frais de stockage, définissant le paiement direct ou par procuration, 1 - paiement direct, 2 - paiement par procuration.ExpediteFlagest le drapeau des frais d'expédition accélérée, définissant le paiement direct ou par procuration, 1 - paiement direct, 2 - paiement par procuration.VmCostConversionRateest le taux de conversion des coûts de la machine virtuelle, avec 2 décimales, uniquement valable pour les paiements par procuration, supérieur à zéro.StorageConversionRateest le taux de conversion des coûts de stockage, avec 2 décimales, uniquement valable pour les paiements par procuration, supérieur à zéro.
Si vous utilisez les paramètres ci-dessus, tous les frais de transaction encourus par les utilisateurs invoquant des contrats au sein de l'écosystème seront payés par le portefeuille écologique de la configuration écologique actuelle.
Tous les utilisateurs n'ont besoin de payer que les frais de gaz encourus au sein de l'écosystème. Bien sûr, vous pouvez ajuster les paramètres de coût selon vos besoins réels.
Écosystème de gouvernance DAO
Avant de modifier vers un écosystème de gouvernance DAO, vous devez vous assurer que l'écosystème actuel a émis des jetons, et après la modification vers un écosystème de gouvernance DAO, toutes les propositions de l'écosystème seront soumises au vote des membres du comité de gouvernance.
Le Conseil de gouvernance DAO n'est plus géré uniquement par les développeurs de l'écosystème, mais les 50 principaux représentants des détenteurs de l'écosystème sont élus.
Call the @1EditControlMode contract to change the eco governance mode to DAO
governance mode.
>callContract @1EditControlMode {"Value": 2}
Où le paramètre Value 1 représente le modèle du créateur et 2 représente
le modèle de gouvernance DAO.
Nous pouvons essayer de créer une application.
>callContract @1NewApplication {"Name": "testApp", "Conditions": "ContractConditions(\"@1DeveloperCondition\")"}
À ce stade, une proposition de gouvernance DAO est générée et votée par le Conseil de gouvernance de la DAO avant la création de l'application. Une proposition valide nécessite un taux d'approbation de 68% sur 75% des votes exprimés.
Le champ d'application de la gouvernance DAO comprend :
- Ajouter, supprimer et modifier des applications, des contrats, des pages, des extraits de code, des onglets, des menus, des paramètres d'application, des tables de données et des champs.
- Modifier le multilingue.
- Changer le modèle de DAO et de créateur.
- Modifier les paramètres écologiques.
- Rôle, assigner ou supprimer des membres de rôle.
- Émettre une monnaie de destruction supplémentaire.
- Modifier les paramètres de la plateforme.
- Modifier les informations écologiques.
- Modification des contrats différés.
- Modifier le modèle de vote.
Déployer des applications à l'aide d'un outil d'emballage d'applications
Avant de commencer ce tutoriel, vous devez télécharger Outil de conditionnement d'application IBAX. Nous devons utiliser cet outil pour empaqueter l'application IBAX.
Nous devons stocker les fichiers de l'application selon la structure de répertoire suivante :
- APP Name
- app_params
params1.csv
params2.csv
...
- contracts
contract1.sim
contract2.sim
...
- tables
tableName1.json
tableName2.json
...
config.json
Comme indiqué ci-dessous:
airdrop$ ls *
config.json
app_params:
dedicated_account.csv lock_percent.csv per_period_sec.csv period_count.csv
contracts:
AddAirdrop.sim ClaimAirdrop.sim SpeedAirdrop.sim
tables:
airdrop_info.json
Le répertoire app_params stocke le fichier des paramètres de l'application,
nommé en utilisant le nom du paramètre + le format de fichier .csv, le contenu
du fichier étant la valeur du paramètre.
Le répertoire contracts contient les contrats, au format de fichier .sim, et
le contenu du fichier est le code source du contrat.
Le répertoire tables contient la structure de la table de données de
l'application au format de fichier json, comme suit:
[
{
"name": "account",
"conditions": "{\"read\": \"true\", \"update\": \"ContractConditions(\"MainCondition\")\"}",
"type": "varchar"
},
{ "name": "balance_amount", "conditions": "true", "type": "money" },
{ "name": "stake_amount", "conditions": "true", "type": "money" },
{ "name": "surplus", "conditions": "true", "type": "number" },
{ "name": "total_amount", "conditions": "true", "type": "money" }
]
name est le nom du champ du tableau de données, conditions est la permission
du champ du tableau de données, et type est le type de champ.
À l'étape 1, nous générons un fichier config.json et le sauvegardons dans le répertoire airdrop avec le contenu suivant :
{
"name": "Airdrop",
"conditions": "ContractConditions(\"@1MainCondition\")"
}
Là où name est le nom de l'application, conditions : est l'autorisation de
modifier l'application, puis l'enregistrer dans le répertoire airdrop.
Étape 2, empaquetez l'application, la commande suivante générera l'application
airdrop.json dans le répertoire actuel. Si vous modifiez le contrat ou les
paramètres de l'application, vous devez reconditionner l'application.
$ ./app-tool airdrop/
Nous pouvons importer l'application via l'outil en ligne de commande command line tool comme suit :
Utilisez la commande import pour importer une application, avec le paramètre
-f pour spécifier le fichier d'application à importer.
$ ibax-cli console
Welcome to the IBAX console!
To exit, press ctrl-d or type exit
>import -f ./airdrop.json
Bien sûr, si vous avez une application, vous pouvez également générer la structure complète du répertoire avec la commande suivante:
$ app-tool.exe airdrop.json