bradyrussell / UISCoin

Java cryptocurrency made to learn more about Bitcoin.
https://bradyrussell.github.io/UISCoin/javadoc
0 stars 1 forks source link
brady coin crypto cryptocurrency java russell uis

UISCoin

UISCoin is my attempt at making a cryptocurrency in Java. It is a SHA512 coin that uses a PoW algorithm based on the number of repeated characters in the set {U, I, S ...} at the beginning of the block hash. UISCoin uses a stack based scripting language much like Bitcoin. Currently standard transactions in UISCoin use P2PKH (pay to public key hash) scripts. All addresses take the form of UIS(v)PUBKEYHASH(checksum) where (v) is a version identifier and (checksum) is a check to ensure the address was not mistyped.

An example address is UISxBraDYN4U4BN4bAKRLenuj1K37xr9zlhAfRFnKu-KLVf89uu3pBBSdBsF45cCAZwLhoK7Litdd4w8GxmkvHgBnFoqXis=

Much like Bitcoin, we are using secp256k1 EC, but we sign messages with SHA512withECDSA. I believe the secp256k1 implementation used was removed in Java 15 so only 14 is supported.

A WIP block explorer can be found at https://uiscoin.bradyrussell.com/ . Here is the source

Differences from Bitcoin

While UISCoin was largely inspired by Bitcoin, there are some intentional differences between the two.

API

JavaDoc is available here: https://bradyrussell.github.io/UISCoin/javadoc

Gradle Dependency:

    repositories {
        maven {
            url "https://repo.bradyrussell.com/repository/bradyrussell-snapshot/"
        }
    }

    dependencies {
        implementation 'com.bradyrussell:UISCoin:1.1+'
    }

I recommend looking at this extension as well: UISCoin_BlockChainStorageLevelDB_Extension Or this one: BlockchainStorageSQL.java

It adds another BlockChainStorage class, this one using a LevelDB database which is much faster than flatfiles.

For a demonstration of the API, here is how I created the Genesis Block.

    public static void CreateGenesisBlock() {
    BlockChain.Initialize(BlockChainStorageFile.class);
    BlockChain.get().open();

    UISCoinKeypair genesisCoins = UISCoinKeypair.Create();
    Wallet.SaveKeypairToFileWithPassword(Path.of("WALLET.uisw"), "PASSWORD", genesisCoins);

    byte[] address = UISCoinAddress.fromPublicKey((ECPublicKey) genesisCoins.Keys.getPublic());
    UISCoinAddress.DecodedAddress decodedAddress = UISCoinAddress.decodeAddress(address);

    long timestamp = Instant.now().getEpochSecond();

    BlockBuilder blockBuilder = new BlockBuilder().setVersion(1)
            .setTimestamp(timestamp)
            .setDifficultyTarget(3)
            .setBlockHeight(0)
            .setHashPreviousBlock(Hash.getSHA512Bytes("UISCoin 1.0 written by Brady Russell. Thanks to https://learnmeabitcoin.com/ and https://www.oreilly.com/library/view/mastering-bitcoin/9781491902639/ for the knowledge."))
            .addCoinbasePayToPublicKeyHash(decodedAddress.PublicKeyHash, "https://www.bbc.com/news - Trump and Melania test positive for coronavirus: The US president and Melania Trump were tested after his close aide was confirmed to have Covid-19. 8m minutes ago US & Canada") /* reference to Satoshi's The Times 03/Jan/2009 Chancellor on brink of second bailout for banks*/
            .CalculateMerkleRoot();

    System.out.println("Begin mining genesis block...");

    int i = Integer.MIN_VALUE;
    while (bIsRunning && !blockBuilder.get().Verify()) {
        blockBuilder.setNonce(i++);
    }

    Block finalBlock = blockBuilder.get();

    System.out.println(Util.Base64Encode(finalBlock.Header.getHash()));

    BlockChain.get().putBlock(finalBlock);
    node.BroadcastBlockToPeers(finalBlock);
    System.out.println("Genesis block broadcast!");
    BlockChain.get().close();
}

Scripting Language

The UISCoin scripting language is executed in bytecode format. See the available OPCodes. Scripts can be converted back and forth between bytecode and script using ScriptBuilder.fromText() and ScriptBuilder.toText(). Scripts can also be created using the Builder pattern as seen below:

            byte[] a  = new ScriptBuilder(128)
            .op(ScriptOperator.DUP) // dup the public key
            .op(ScriptOperator.SHA512) // hash it
            .push(A) // push the address
            .op(ScriptOperator.LEN) // take its length
            .pushInt(4) // push 4
            .op(ScriptOperator.SWAP) // make length the top stack element, then 4
            .op(ScriptOperator.SUBTRACT) // do length - 4
            .op(ScriptOperator.LIMIT) // limit the address to length - 4 (remove checksum)
            .op(ScriptOperator.BYTESEQUAL) // equal to pubkey hash?
            .op(ScriptOperator.VERIFY)
            .op(ScriptOperator.VERIFYSIG)
            .get();

            byte[] b= new ScriptBuilder(128).fromText("dup sha512").push(A).fromText("len push 4 swap subtract limit bytesequal verify verifysig").get();
            assertTrue(Arrays.equals(a,b));// true

I am working on an IDE for scripts which can be seen here: Image of Script Editor