11package com .bloxbean .cardano .aiken .tx .evaluator ;
22
3+ import com .bloxbean .cardano .aiken .AikenTransactionEvaluator ;
34import com .bloxbean .cardano .client .account .Account ;
45import com .bloxbean .cardano .client .address .AddressProvider ;
56import com .bloxbean .cardano .client .api .ProtocolParamsSupplier ;
1112import com .bloxbean .cardano .client .backend .api .BackendService ;
1213import com .bloxbean .cardano .client .backend .api .DefaultProtocolParamsSupplier ;
1314import com .bloxbean .cardano .client .backend .api .DefaultUtxoSupplier ;
14- import com .bloxbean .cardano .client .backend .koios .KoiosBackendService ;
15- import com .bloxbean .cardano .client .backend .model .TransactionContent ;
16- import com .bloxbean .cardano .client .coinselection .UtxoSelectionStrategy ;
17- import com .bloxbean .cardano .client .coinselection .impl .LargestFirstUtxoSelectionStrategy ;
15+ import com .bloxbean .cardano .client .backend .blockfrost .common .Constants ;
16+ import com .bloxbean .cardano .client .backend .blockfrost .service .BFBackendService ;
1817import com .bloxbean .cardano .client .common .CardanoConstants ;
1918import com .bloxbean .cardano .client .common .model .Networks ;
2019import com .bloxbean .cardano .client .exception .CborSerializationException ;
21- import com .bloxbean .cardano .client .function .Output ;
22- import com .bloxbean .cardano .client .function .TxBuilder ;
23- import com .bloxbean .cardano .client .function . TxBuilderContext ;
24- import com .bloxbean .cardano .client .function . TxSigner ;
25- import com .bloxbean .cardano .client .function . helper .* ;
26- import com .bloxbean .cardano .client .function . helper . model . ScriptCallContext ;
27- import com .bloxbean .cardano .client .plutus . spec .* ;
28- import com .bloxbean .cardano .client .transaction . spec .* ;
29- import com .bloxbean .cardano .client .transaction .util . CostModelUtil ;
20+ import com .bloxbean .cardano .client .function .helper . ScriptUtxoFinders ;
21+ import com .bloxbean .cardano .client .function .helper . SignerProviders ;
22+ import com .bloxbean .cardano .client .plutus . spec . BigIntPlutusData ;
23+ import com .bloxbean .cardano .client .plutus . spec . PlutusData ;
24+ import com .bloxbean .cardano .client .plutus . spec . PlutusV2Script ;
25+ import com .bloxbean .cardano .client .quicktx . QuickTxBuilder ;
26+ import com .bloxbean .cardano .client .quicktx . ScriptTx ;
27+ import com .bloxbean .cardano .client .quicktx . Tx ;
28+ import com .bloxbean .cardano .client .transaction .spec . TransactionInput ;
3029import com .bloxbean .cardano .client .util .JsonUtil ;
31- import org .assertj .core .util .Lists ;
3230import org .junit .jupiter .api .Assertions ;
3331import org .junit .jupiter .api .Test ;
3432
3533import java .math .BigInteger ;
36- import java .util .Collections ;
37- import java .util .HashSet ;
3834import java .util .List ;
39- import java .util .Set ;
40-
41- import static com .bloxbean .cardano .client .common .ADAConversionUtil .adaToLovelace ;
35+ import java .util .Optional ;
4236
4337//The caller has to guess the sum of 0..datum_value to claim the locked fund.
4438public class GuessSumContractIntegrationTest {
@@ -49,8 +43,8 @@ public class GuessSumContractIntegrationTest {
4943
5044 String senderAddress = sender .baseAddress ();
5145
52- BackendService backendService = new KoiosBackendService (com .bloxbean .cardano .client .backend .koios .Constants .KOIOS_PREPROD_URL );
53-
46+ // BackendService backendService = new KoiosBackendService(com.bloxbean.cardano.client.backend.koios.Constants.KOIOS_PREPROD_URL);
47+ BackendService backendService = new BFBackendService ( Constants . BLOCKFROST_PREPROD_URL , System . getenv ( "BF_PROJECT_ID" ));
5448 private UtxoSupplier utxoSupplier = new DefaultUtxoSupplier (backendService .getUtxoService ());
5549
5650 private ProtocolParamsSupplier protocolParamsSupplier = new DefaultProtocolParamsSupplier (backendService .getEpochService ());
@@ -71,133 +65,68 @@ public void invokeContract() throws Exception {
7165 PlutusData datum = BigIntPlutusData .of (8 );
7266
7367 lockFundWithInlineDatum (scriptAddress , datum ); //CIP-32
68+ Thread .sleep (4000 ); //To avoid retrieving utxo which was just spent
7469
7570 //3. Claim fund by guessing the sum
7671 //Get script utxo
77-
7872 Utxo scriptUtxo = ScriptUtxoFinders .findFirstByDatumHashUsingDatum (utxoSupplier , scriptAddress , datum ).orElseThrow ();
7973 BigInteger claimAmount = scriptUtxo
8074 .getAmount ().stream ().filter (amount -> CardanoConstants .LOVELACE .equals (amount .getUnit ()))
8175 .findFirst ()
8276 .orElseThrow ().getQuantity ();
8377
84- Output output = Output .builder ()
85- .address (senderAddress )
86- .assetName (CardanoConstants .LOVELACE )
87- .qty (claimAmount )
88- .build ();
89-
90- ScriptCallContext scriptCallContext = ScriptCallContext
91- .builder ()
92- .script (sumScript )
93- .exUnits (ExUnits .builder () //Exact exUnits will be calculated later
94- .mem (BigInteger .valueOf (0 ))
95- .steps (BigInteger .valueOf (0 ))
96- .build ())
97- .redeemer (BigIntPlutusData .of (36 ))
98- .redeemerTag (RedeemerTag .Spend ).build ();
99-
100- // Find collaterals
101- UtxoSelectionStrategy utxoSelectionStrategy = new LargestFirstUtxoSelectionStrategy (utxoSupplier );
102-
103- Set <Utxo > collateralUtxos =
104- utxoSelectionStrategy .select (senderAddress , new Amount (CardanoConstants .LOVELACE , adaToLovelace (5 )), Collections .emptySet ());
105-
10678 //Get reference input
10779 TransactionInput refInput = new TransactionInput ("5a47b9a4276362000566ac5e58c18f315440a78a8cb0a8d1fe066e0012bcfbab" , 0 );
108- //Hardcoding referenceInputUtxo for now. This will be removed after https://github.com/bloxbean/cardano-client-lib/pull/241
109- Utxo referenceInputUtxo = Utxo .builder ()
110- .address ("addr_test1wzcppsyg36f65jydjsd6fqu3xm7whxu6nmp3pftn9xfgd4ckah4da" )
111- .txHash (refInput .getTransactionId ())
112- .outputIndex (refInput .getIndex ())
113- .amount (List .of (new Amount (CardanoConstants .LOVELACE , adaToLovelace (9.34408 ))))
114- .referenceScriptHash ("b010c0888e93aa488d941ba4839136fceb9b9a9ec310a573299286d7" )
115- .build ();
116-
117- TxBuilder contractTxBuilder = output .outputBuilder ()
118- .buildInputs (InputBuilders .createFromUtxos (List .of (scriptUtxo )))
119- .andThen (InputBuilders .referenceInputsFrom (List .of (refInput )))
120- .andThen (CollateralBuilders .collateralOutputs (senderAddress , Lists .newArrayList (collateralUtxos ))) //CIP-40
121- .andThen (ScriptCallContextProviders .createFromScriptCallContext (scriptCallContext ))
122- .andThen ((context , txn ) -> {
123- CostMdls costMdls = new CostMdls ();
124- costMdls .add (CostModelUtil .PlutusV2CostModel );
125-
126- //Fix required in cardano-client-lib to also include reference input utxo in the context
127- Set <Utxo > utxos = new HashSet <>(context .getUtxos ());
128- utxos .add (referenceInputUtxo );
129-
130- //Evaluate ExUnits
131- SlotConfig slotConfig = new SlotConfig (1000 , 0 , 100 );
132- InitialBudgetConfig initialBudgetConfig = new InitialBudgetConfig (14000000L , 10000000000L );
133- TxEvaluator txEvaluator = new TxEvaluator (slotConfig , initialBudgetConfig );
134- List <Redeemer > redeemerList = txEvaluator .evaluateTx (txn , utxos , costMdls );
135- txn .getWitnessSet ().getRedeemers ().get (0 ).setExUnits (redeemerList .get (0 ).getExUnits ());
136-
137- System .out .println ("ExUnits evaluation From Aiken:" + redeemerList );
138-
80+ ScriptTx tx = new ScriptTx ()
81+ .payToAddress (senderAddress , Amount .lovelace (claimAmount ))
82+ .collectFrom (scriptUtxo , BigIntPlutusData .of (36 ))
83+ .readFrom (refInput .getTransactionId (), refInput .getIndex ())
84+ .attachSpendingValidator (sumScript );
85+
86+ QuickTxBuilder quickTxBuilder = new QuickTxBuilder (backendService );
87+ Result <String > result = quickTxBuilder .compose (tx )
88+ .feePayer (senderAddress )
89+ .withSigner (SignerProviders .signerFrom (sender ))
90+ .withTxInspector (transaction -> System .out .println (JsonUtil .getPrettyJson (transaction )))
91+ .withTxEvaluator (new AikenTransactionEvaluator (backendService ))
92+ .postBalanceTx ((context , txn ) -> {
93+ //Remove all script witness sets as we are using reference inptuts
13994 txn .getWitnessSet ().getPlutusV2Scripts ().clear ();
140- })
141- .andThen (BalanceTxBuilders .balanceTx (senderAddress , 2 ));
142-
143- TxBuilderContext txBuilderContext = TxBuilderContext .init (utxoSupplier , protocolParamsSupplier );
144-
145- //Tx Build and Submit
146- TxSigner signer = SignerProviders .signerFrom (sender );
147-
148- Transaction signedTx = txBuilderContext
149- .buildAndSign (contractTxBuilder , signer );
150-
151- Result <String > result = backendService .getTransactionService ().submitTransaction (signedTx .serialize ());
95+ }).completeAndWait (System .out ::println );
15296
15397 System .out .println ("Unlock Tx: " + result );
154-
15598 Assertions .assertTrue (result .isSuccessful ());
156- waitForTransaction (result );
15799 }
158100
159101 private void lockFundWithInlineDatum (String scriptAddress , PlutusData datum ) throws ApiException , CborSerializationException {
160- Output lockOutput = Output .builder ()
161- .address (scriptAddress )
162- .assetName (CardanoConstants .LOVELACE )
163- .qty (adaToLovelace (4 ))
164- .datum (datum )
165- .inlineDatum (true ).build ();
166-
167- TxBuilder lockFundTxBuilder = lockOutput .outputBuilder ()
168- .buildInputs (InputBuilders .createFromSender (senderAddress , senderAddress ))
169- .andThen (BalanceTxBuilders .balanceTx (senderAddress , 1 ));
102+ Tx tx = new Tx ()
103+ .payToContract (scriptAddress , Amount .ada (4.0 ), datum )
104+ .from (senderAddress );
170105
171- Transaction signedTx = TxBuilderContext .init (utxoSupplier , protocolParamsSupplier )
172- .buildAndSign (lockFundTxBuilder , SignerProviders .signerFrom (sender ));
106+ QuickTxBuilder quickTxBuilder = new QuickTxBuilder (backendService );
107+ Result <String > result = quickTxBuilder .compose (tx )
108+ .withSigner (SignerProviders .signerFrom (sender ))
109+ .completeAndWait (System .out ::println );
173110
174- Result < String > result = backendService . getTransactionService (). submitTransaction ( signedTx . serialize () );
175- System . out . println ( "Lock Tx: " + result );
111+ System . out . println ( "Lock Tx: " + result );
112+ Assertions . assertTrue ( result . isSuccessful () );
176113
177- Assertions .assertTrue (result .isSuccessful ());
178- waitForTransaction (result );
114+ checkIfUtxoAvailable (result .getValue (), scriptAddress );
179115 }
180116
181- private void waitForTransaction (Result <String > result ) {
182- try {
183- if (result .isSuccessful ()) { //Wait for transaction to be mined
184- int count = 0 ;
185- while (count < 60 ) {
186- Result <TransactionContent > txnResult = backendService .getTransactionService ().getTransaction (result .getValue ());
187- if (txnResult .isSuccessful ()) {
188- System .out .println (JsonUtil .getPrettyJson (txnResult .getValue ()));
189- break ;
190- } else {
191- System .out .println ("Waiting for transaction to be mined ...." );
192- }
193-
194- count ++;
195- Thread .sleep (2000 );
196- }
197- }
198- } catch (Exception e ) {
199- e .printStackTrace ();
117+ protected void checkIfUtxoAvailable (String txHash , String address ) {
118+ Optional <Utxo > utxo = Optional .empty ();
119+ int count = 0 ;
120+ while (utxo .isEmpty ()) {
121+ if (count ++ >= 20 )
122+ break ;
123+ List <Utxo > utxos = new DefaultUtxoSupplier (backendService .getUtxoService ()).getAll (address );
124+ utxo = utxos .stream ().filter (u -> u .getTxHash ().equals (txHash ))
125+ .findFirst ();
126+ System .out .println ("Try to get new output... txhash: " + txHash );
127+ try {
128+ Thread .sleep (1000 );
129+ } catch (Exception e ) {}
200130 }
201131 }
202-
203132}
0 commit comments