Skip to content

Commit

Permalink
finished payment-channels
Browse files Browse the repository at this point in the history
  • Loading branch information
neodix42 committed Nov 22, 2022
1 parent e556a8e commit cd207ab
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 43 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,12 @@ You can use each submodule individually. Click the module below to get more deta
* ✅ Get block transactions
* ✅ Get account transactions
* ✅ Deploy contracts and send external messages using Tonlib
* ✅ Wallet operations (Simple (V1), V2, V3, V4 (plugins), ~~Lockup~~, DNS, Jetton, NFT)
* ✅ Wallet operations (Simple (V1), V2, V3, V4 (plugins), ~~Lockup~~, DNS, Jetton, NFT, Payment-channels)
* ✅ HashMap, HashMapE, PfxHashMap and PfxHashMapE serialization / deserialization

### Todo
* Re-test lockup (restricted) wallet
* Support tuple and list as arguments for runMethod
* Add TON Payment channel support
* Add highload wallet support
* Fix dictionary de/serialization with one entry
* Improve test coverage and add more integration tests
Expand Down
1 change: 1 addition & 0 deletions smartcontract/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Currently, following wallet versions and revisions are supported:
* Dns [(see usage example)](dns-example.md)
* Jetton [(see usage example)](jetton-example.md)
* NFT [(see usage example)](nft-example.md)
* Payment channels [(see usage example)](./src/test/java/org/ton/java/smartcontract/integrationtests/TestPayments.java)
* Custom contract [(see usage example)](custom-smc-example.md)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@
import org.ton.java.smartcontract.wallet.Options;
import org.ton.java.smartcontract.wallet.WalletContract;
import org.ton.java.tonlib.Tonlib;
import org.ton.java.utils.Utils;

import java.math.BigInteger;

import static java.util.Objects.nonNull;


public class FromWallet extends PaymentChannel {

Options options;
Expand All @@ -33,26 +31,22 @@ public FromWallet(Tonlib tonlib, WalletContract wallet, byte[] secretKey, Option
}

public FromWallet deploy(BigInteger amount) {
Utils.sleep(1, "deploying");
transfer(null, true, amount);
return this;
}

public FromWallet topUp(BigInteger balanceA, BigInteger balanceB, BigInteger amount) {
Utils.sleep(1, "topup");
transfer(this.createTopUpBalance(balanceA, balanceB), amount);
return this;
}

public FromWallet init(BigInteger balanceA, BigInteger balanceB, BigInteger amount) {
Utils.sleep(1, "init");
transfer(this.createInitChannel(balanceA, balanceB).getCell(), amount);
return this;
}


public FromWallet send() { // todo estimateFee
Utils.sleep(1, "sending");
public FromWallet send() {
if (nonNull(extMsg)) {
tonlib.sendRawMessage(extMsg.message.toBocBase64(false));
} else {
Expand All @@ -61,6 +55,15 @@ public FromWallet send() { // todo estimateFee
return this;
}

public FromWallet estimateFee() {
if (nonNull(extMsg)) {
tonlib.estimateFees(extMsg.address.toString(), extMsg.message.toBocBase64(false), extMsg.code.toBocBase64(false), extMsg.data.toBocBase64(false), false);
} else {
throw new Error("cannot send empty external message");
}
return this;
}

public FromWallet close(ChannelState channelState, byte[] hisSignature, BigInteger amount) {
transfer(this.createCooperativeCloseChannel(hisSignature, channelState).getCell(), amount);
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ public static void setUpClass() throws InterruptedException {
// The payment channel is established between two participants A and B.
// Each has own secret key, which he does not reveal to the other.

walletA = GenerateWallet.random(tonlib, 7);
walletB = GenerateWallet.random(tonlib, 7);
walletA = GenerateWallet.random(tonlib, 3);
walletB = GenerateWallet.random(tonlib, 3);
walletAddressA = walletA.getWallet().getAddress();
walletAddressB = walletB.getWallet().getAddress();
}
Expand Down Expand Up @@ -100,37 +100,6 @@ public void testPayments() {

assertThat(channelA.getAddress().toString(true, true, true)).isEqualTo(channelB.getAddress().toString(true, true, true));

// Interaction with the smart contract of the payment channel is carried out by sending messages from the wallet to it.
// So let's create helpers for such sends.

// InitExternalMessage msg = channelB.createInitExternalMessage(walletA.getKeyPair().getSecretKey());
// log.info("in {}", msg);
// BigInteger balance = TestFaucet.topUpContract(tonlib, Address.of(msg.address.toString(true, true, false)), Utils.toNano(1));
// log.info("balance {}", Utils.formatNanoValue(balance));
// tonlib.sendRawMessage(msg.message.toBocBase64(false));
// Cannot run message on account: inbound external message rejected by transaction CDE825A804357B8E9390941832574F35A5DE8750AD6FC034A4041F7A953197F9:
// exitcode=65535, steps=54, gas_used=0
// VM Log (truncated):
//... PUSHCONT x30F017DB31
// execute IFJMP
// execute NIP
// execute PUSHINT 625158801
// execute EQUAL
// execute PUSHCONT xF018DB31
// execute IFJMP
// execute implicit JMPREF
// execute PUSHPOW2DEC 16
// execute THROWANY
// default exception handler, terminating vm with exit code 65535


// channelA.transfer(walletA.getWallet(), walletA.getKeyPair().getSecretKey(), tonlib, null, true, Utils.toNano(0.05));
// channelA.send(tonlib);
// liteServer_sendMsgStatus = 1 , OK
// msg does not come to chanelA contract at all
// Bounced op=no-op from channel-smc


FromWallet fromWalletA = channelA.fromWallet(tonlib, walletA.getWallet(), walletA.getKeyPair().getSecretKey());
FromWallet fromWalletB = channelB.fromWallet(tonlib, walletB.getWallet(), walletB.getKeyPair().getSecretKey());

Expand All @@ -155,9 +124,10 @@ public void testPayments() {
// Now each parties must send their initial balance from the wallet to the channel contract.

fromWalletA.topUp(channelInitState.getBalanceA(), BigInteger.ZERO, channelInitState.getBalanceA().add(Utils.toNano(0.05))).send(); // +0.05 TON to network fees
Utils.sleep(25, "topping up from wallet A...");
fromWalletB.topUp(BigInteger.ZERO, channelInitState.getBalanceB(), channelInitState.getBalanceB().add(Utils.toNano(0.05))).send(); // +0.05 TON to network fees
Utils.sleep(25, "topping up from wallet B...");

Utils.sleep(25, "topping up...");
log.info("channel A state {}", channelA.getChannelState(tonlib));

log.info("channel A data {}", channelA.getData(tonlib));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.ton.java.smartcontract.wallet.v1.SimpleWalletContractR3;
import org.ton.java.tonlib.Tonlib;
import org.ton.java.tonlib.types.AccountState;
import org.ton.java.tonlib.types.QueryFees;
import org.ton.java.utils.Utils;

import java.math.BigInteger;
Expand Down Expand Up @@ -89,4 +90,28 @@ public void testNewWalletSimple() throws InterruptedException {
log.info("seqno {}", contract.getSeqno(tonlib));
log.info("pubkey {}", contract.getPublicKey(tonlib));
}

@Test
public void testWalletSimpleEstimateFees() {
TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair();

Options options = Options.builder()
.publicKey(keyPair.getPublicKey())
.wc(0L)
.build();

Wallet wallet = new Wallet(WalletVersion.simpleR3, options);
SimpleWalletContractR3 contract = wallet.create();

InitExternalMessage msg = contract.createInitExternalMessage(keyPair.getSecretKey());

Tonlib tonlib = Tonlib.builder().testnet(true).build();

QueryFees feesWithCodeData = tonlib.estimateFees(msg.address.toString(), msg.message.toBocBase64(false), msg.code.toBocBase64(false), msg.data.toBocBase64(false), false);
log.info("fees {}", feesWithCodeData);
assertThat(feesWithCodeData).isNotNull();
QueryFees feesBodyOnly = tonlib.estimateFees(msg.address.toString(), msg.message.toBocBase64(false), null, null, false);
log.info("fees {}", feesBodyOnly);
assertThat(feesBodyOnly).isNotNull();
}
}

0 comments on commit cd207ab

Please sign in to comment.