Skip to content
This repository has been archived by the owner on Dec 7, 2021. It is now read-only.

Transanction modifed and 2 demos added #5

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,10 @@
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java/NEO/data</directory>
</resource>
</resources>
</build>
</project>
123 changes: 123 additions & 0 deletions src/main/java/Demo/GlobalAssetDemo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package Demo;

import NEO.Core.Blockchain;
import NEO.Core.SignatureContext;
import NEO.Core.Transaction;
import NEO.Fixed8;
import NEO.Helper;
import NEO.IO.Json.JArray;
import NEO.IO.Json.JNumber;
import NEO.IO.Json.JObject;
import NEO.IO.Json.JString;
import NEO.Settings;
import NEO.UInt160;
import NEO.Wallets.Account;
import NEO.Wallets.Contract;
import NEO.Wallets.Wallet;
import NEO.sdk.SmartContractTx;
import NEO.sdk.wallet.AccountManager;

import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;

public class GlobalAssetDemo {

// exported WIF from wallet
public static final String WALLET_WIF1 = "KxQVgnGyoHNA9h4k2as9TDPczsSwzUbH2Y8Bfku65AJiomB3wkg6";
public static final String WALLET_WIF2 = "L4vr3XmcqGNJzwVfABiVtZbJajhNUWv6ny9Ggv7HYbhBy8rxMReU";
public Contract contract;

public static void main(String[] args) throws Exception {

// import setting
Settings.getSettings(Settings.CONFIG_PRIVNET);

// new AccountManager
AccountManager wm = getAccountManager();

// start block sync
wm.startSyncBlock();

// check height
while (!wm.hasFinishedSyncBlock()) {
Thread.sleep(1000 * 1);
}

// import two account from WIF
String address1 = wm.createAccountsFromPrivateKey(Helper.toHexString(Wallet.getPrivateKeyFromWIF(WALLET_WIF1)));
Account account1 = wm.getAccount(address1);
Contract contract1 = Contract.createSignatureContract(account1.publicKey);
System.out.println("contract1 address:" + address1);

String address2 = wm.createAccountsFromPrivateKey(Helper.toHexString(Wallet.getPrivateKeyFromWIF(WALLET_WIF2)));
Account account2 = wm.getAccount(address2);
Contract contract2 = Contract.createSignatureContract(account2.publicKey);
System.out.println("contract2 address:" + address2);

// check balance
System.out.println(wm.getAccountAsset(address1));
System.out.println(wm.getAccountAsset(address2));

// make transaction
Fixed8 fee = new Fixed8();
Transaction tx = SmartContractTx.makeContractTransaction(address2, Blockchain.GoverningToken, Fixed8.ONE, fee);
System.out.println(tx.hash().toString());
tx = wm.makeTransaction(tx, fee, Wallet.toScriptHash(address1));

// sign tx
SignatureContext context = new SignatureContext(tx, new UInt160[]{Wallet.toScriptHash(contract1.address())});
byte[] signature = context.signable.sign(account1);
if (!context.add(contract1, account1.publicKey, signature))
throw new Exception();
if (context.isCompleted()) {
tx.scripts = context.getScripts();
System.out.println("scripts:" + tx.scripts[0].json());
}

// checkout transaction
String txHex = Helper.toHexString(tx.toArray());
System.out.println("tx:" + tx.json());

// make request
JObject[] params = new JObject[]{ new JString(Helper.toHexString(tx.toArray())) };

JObject request = new JObject();
request.set("jsonrpc", new JString("2.0"));
request.set("method", new JString("sendrawtransaction"));
request.set("params", new JArray(params));
request.set("id", new JNumber(1));

// send request
HttpURLConnection connection = (HttpURLConnection) new URL(Settings.RPC_LIST.get(0)).openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);

// wait result
try (OutputStreamWriter w = new OutputStreamWriter(connection.getOutputStream())) {
w.write(request.toString());
}
try (InputStreamReader r = new InputStreamReader(connection.getInputStream())) {
System.out.println(JObject.parse(r));
}
}

public static AccountManager getAccountManager() throws MalformedURLException {
// v1.2
String neoUrl = Settings.RPC_LIST.get(0);
String neoToken = "";
String path = "./1.db3";
AccountManager wm = AccountManager.getWallet(path, neoUrl, neoToken);
print(String.format("[param=%s,%s]", neoUrl, path));
print(String.format("start to test....hh:%s", wm.getBlockHeight()));
return wm;
}

private static void print(String ss) {
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()) + " " + ss);
}
}
136 changes: 136 additions & 0 deletions src/main/java/Demo/RawTxDemo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package Demo;

import NEO.*;
import NEO.Core.*;
import NEO.Core.Scripts.Program;
import NEO.IO.Json.JArray;
import NEO.IO.Json.JNumber;
import NEO.IO.Json.JObject;
import NEO.IO.Json.JString;
import NEO.Wallets.Account;
import NEO.Wallets.Contract;
import NEO.Wallets.Wallet;
import NEO.sdk.wallet.AccountManager;

import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;

public class RawTxDemo {

// exported WIF from wallet
public static final String WALLET_WIF2 = "KxDgvEKzgSBPPfuVfw67oPQBSjidEiqTHURKSDL1R7yGaGYAeYnr";
public static final String WALLET_WIF1 = "L4vr3XmcqGNJzwVfABiVtZbJajhNUWv6ny9Ggv7HYbhBy8rxMReU";
public Contract contract;

public static void main(String[] args) throws Exception {

// import setting
Settings.getSettings(Settings.CONFIG_PRIVNET);

// new AccountManager
String neoUrl = Settings.RPC_LIST.get(0);
String neoToken = "";
String path = "./1.db3";
AccountManager wm = AccountManager.getWallet(path, neoUrl, neoToken);
System.out.println("[param=" + neoUrl + "," + path + "]");
System.out.println("start to test....hh:" + wm.getBlockHeight());

// start block sync
wm.startSyncBlock();

// check height
while (!wm.hasFinishedSyncBlock()) {
Thread.sleep(1000 * 1);
}

// import two account from WIF
String address1 = wm.createAccountsFromPrivateKey(Helper.toHexString(Wallet.getPrivateKeyFromWIF(WALLET_WIF1)));
Account account1 = wm.getAccount(address1);
Contract contract1 = Contract.createSignatureContract(account1.publicKey);
System.out.println("contract1 address:" + address1);

String address2 = wm.createAccountsFromPrivateKey(Helper.toHexString(Wallet.getPrivateKeyFromWIF(WALLET_WIF2)));
Account account2 = wm.getAccount(address2);
Contract contract2 = Contract.createSignatureContract(account2.publicKey);
System.out.println("contract2 address:" + address2);

// check balance
System.out.println(wm.getAccountAsset(address1));
System.out.println(wm.getAccountAsset(address2));

// make transaction
ContractTransaction tx = new ContractTransaction();

// neo input
TransactionInput inputN = new TransactionInput();
inputN.prevIndex = 0;
inputN.prevHash = UInt256.parse("072497994952d898e4f302d7b7022cbfd368d2b2ede4f51a0a3e41af22278e87");

// gas input
TransactionInput inputG = new TransactionInput();
inputG.prevIndex = 0;
inputG.prevHash = UInt256.parse("ede0cfea66811f194c1d82b8d8377f941c8cc8bae3adfed0a77c5eb7bb5e96a9");

// neo output
TransactionOutput outputN = new TransactionOutput();
outputN.assetId = Blockchain.GoverningToken;
outputN.value = Fixed8.ONE;
outputN.scriptHash = Wallet.toScriptHash(address2);

// gas output
TransactionOutput outputG = new TransactionOutput();
outputG.assetId = Blockchain.UtilityToken;
outputG.value = new Fixed8((long)(0.999 * (long)Math.pow(10, 8)));
outputG.scriptHash = Wallet.toScriptHash(address1);

tx.version = 0;
tx.attributes = new TransactionAttribute[0];
tx.inputs = new TransactionInput[2];
tx.inputs[0] = inputN;
tx.inputs[1] = inputG;
tx.outputs = new TransactionOutput[2];
tx.outputs[0] = outputN;
tx.outputs[1] = outputG;
tx.scripts = new Program[0];

System.out.println(tx.hash().toString());

// sign tx
SignatureContext context = new SignatureContext(tx, new UInt160[]{Wallet.toScriptHash(contract1.address())});
byte[] signature = context.signable.sign(account1);
if (!context.add(contract1, account1.publicKey, signature))
throw new Exception();
if (context.isCompleted()) {
tx.scripts = context.getScripts();
System.out.println("scripts:" + tx.scripts[0].json());
}

// checkout transaction
String txHex = Helper.toHexString(tx.toArray());
System.out.println("tx:" + tx.json());

// make request
JObject[] params = new JObject[]{ new JString(Helper.toHexString(tx.toArray())) };

JObject request = new JObject();
request.set("jsonrpc", new JString("2.0"));
request.set("method", new JString("sendrawtransaction"));
request.set("params", new JArray(params));
request.set("id", new JNumber(1));

// send request
HttpURLConnection connection = (HttpURLConnection) new URL(Settings.RPC_LIST.get(0)).openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);

// wait result
try (OutputStreamWriter w = new OutputStreamWriter(connection.getOutputStream())) {
w.write(request.toString());
}
try (InputStreamReader r = new InputStreamReader(connection.getInputStream())) {
System.out.println(JObject.parse(r));
}
}
}
4 changes: 4 additions & 0 deletions src/main/java/NEO/Core/Blockchain.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ public abstract class Blockchain implements AutoCloseable {
@Override
public abstract void close();

public static final UInt256 GoverningToken = UInt256.parse("c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b");

public static final UInt256 UtilityToken = UInt256.parse("602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7");

/**
* 判断区块链中是否包含指定的资产
* <param name="hash">资产编号</param>
Expand Down
58 changes: 58 additions & 0 deletions src/main/java/NEO/Core/ClaimTransaction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package NEO.Core;

import NEO.IO.BinaryReader;
import NEO.IO.BinaryWriter;
import NEO.UInt160;
import NEO.UInt256;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class ClaimTransaction extends Transaction{

public TransactionInput[] claims;

public ClaimTransaction() {
super(TransactionType.ClaimTransaction);
}

@Override
protected void deserializeExclusiveData(BinaryReader reader) throws IOException {
try {
claims = reader.readSerializableArray(TransactionInput.class);
}
catch (Exception e) {
throw new IOException();
}
}

@Override
public UInt160[] getScriptHashesForVerifying() {
HashSet<UInt160> hashs = new HashSet<UInt160>(Arrays.asList(super.getScriptHashesForVerifying()));
for (Map.Entry<UInt256, List<TransactionInput>> group : Arrays.stream(claims).collect(Collectors.groupingBy(p -> p.prevHash)).entrySet()) {
try {
Transaction tx = Blockchain.current().getTransaction(group.getKey());
if (tx == null)
throw new IllegalStateException();
for (TransactionInput claim : group.getValue()) {
if (tx.outputs.length <= claim.prevIndex)
throw new IllegalStateException();
hashs.add(tx.outputs[claim.prevIndex].scriptHash);
}
}
catch (Exception e) {
throw new IllegalStateException();
}
}
return hashs.stream().sorted().toArray(UInt160[]::new);
}

@Override
protected void serializeExclusiveData(BinaryWriter writer) throws IOException {
writer.writeSerializableArray(claims);
}
}
15 changes: 12 additions & 3 deletions src/main/java/NEO/Core/MinerTransaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ public MinerTransaction() {

@Override
protected void deserializeExclusiveData(BinaryReader reader) throws IOException {
if(version == 3) {
nonce = reader.readLong();
}
nonce = reader.readInt();
}

@Override
Expand All @@ -25,4 +23,15 @@ protected void serializeExclusiveData(BinaryWriter writer) throws IOException {
writer.writeLong(nonce);
}
}

@Override
protected void onDeserialized() throws IOException{
if (inputs.length != 0)
throw new IOException();
for (TransactionOutput output : outputs) {
//if (output.assetId != Blockchain.utilityToken().hash())
if (output.assetId != Blockchain.UtilityToken)
throw new IOException();
}
}
}
Loading