GAJU: Create and Call a Gajumaru Smart Contract

“Smart contract” is a bad term.

It is malicious antisense made up by a marketing department with the intent of warping the intuitions of non-experts in dangerous ways. A much better term would be “ledger logic” or “chain script” or even “weave” or “doom” or something like that — because a “smart contract” is just a deterministic program. They are barely even programs, have nothing to do with “contracts”, and there isn’t anything particularly “smart” about them.

Smart contracts are simply collections of deterministic, algorithmic state transition rules.

Think of a “smart contract” as a collection of functions, some related data, and an account ID on chain the functions have access to, because that’s all they are. The reason there is an account component to a contract is so that you can have it handle money, and the only reason it is safe to let a smart contract handle money is because the rules you write for it are required to be completely deterministic.

This is actually a really useful idea, but not for the reasons that the term “smart contract” would lead you to believe at first, and that’s why it is a bad term. I wish we had something else, but that term seems to have stuck, so whatever. The takeaway is that smart contracts are a very good idea, they just have a stupid name.

Gajumaru “Hello World”

Getting started with Gajumaru is almost comically easy by comparison to any other blockchain system.

In fact, even if you don’t like Gajumaru or plan to build on some other chain in the future, if anyone were to ask me how to get started with blockchain I would absolutely recommend Gajumaru as the place to figure things out and become familiar with the concepts encountered all over blockchain. The tooling for contract development is all just built in to the desktop wallet thingy, GajuDesk, and “just works”.

Getting GajuDesk

If you’re on Mac or Windows you download the installer and run it (get the GajuDesk one, unless you want to mine also, then get the GajuMine installer — it provides both), and you will have a complete contract development environment already. If you’re on Linux, get Erlang + zx and type zx run gajudesk and it will build itself and start.

It will open with a little screen about whether you’re new and need a default wallet and account generated, or if you’re importing an existing one. Pick that you’re new and you need a new wallet set up.

At wallet creation there is a little toggle thing for whether to create a mainnet wallet or a testnet wallet. Select testnet. Name it whatever you want, and you can set a password or not — who cares, testnet Gajus are monopoly money anyway.

Next, on the main GajuDesk screen, click the “copy” button in the lower right. That will copy the currently selected account ID to the desktop clipboard so you can paste it. Then go to the faucet and paste the account ID in and click the “Send me 木10” to get 10 Gajus.

The transaction will happen within a second or three, but the wallet might not reflect the update for a few seconds.

With some gajus in your account, you can now do contract stuff!

There is a function button in the top right of the app that looks like f()→ . If you click it a new interface window will open called FateWeaver. That’s the contract development interface.

At the top there are a few options. We want to click “new”. That will open a file dialog thingy that will ask you were you want to put the save location. Pick somewhere. Anywhere.

Now you will have a blank text editor window and wonder “OK, so now what?”

We’ll write a little tiny “Hello, World!” style program and put it on the testnet, that’s what!

The simplest “Hello, World!”

A “Hello, world!” program is supposed to do a single thing: get “Hello, world!” on the screen as efficiently as possible. This demonstrates to a newcomer to any language a lot about how the language works, because it requires us to go through every step to set up a program, initialize its state, and interact with the user, at least a tiny bit.

In Sophia this is quite simple, and interacting with the chain via GajuDesk is super simple.

Here is our program:

@compiler == 9.0.0

contract Hello =
  record state =
    {greeting : string}

  entrypoint init() : state =
    {greeting = "Hello, world!"}

  entrypoint greet() : string =
    state.greeting

In FateWeaver it looks like this:

That top line there is pretty important if you want people to be able to verify your program in the future, so definitely have that. And don’t do the @compiler >= 9.0.0 form. That reads as “this or any higher version”, which removes the possibility of reproducible (and therefore verifiable) builds in the future.

As you can tell, this is a language with some semantic whitespace going on. Nice.

The first thing we have to declare is contract because that’s what we are writing. A contract is kind of like a class or object definition in an OOP language, because there is a blob of state data (conveniently called state above) that is the property of the given contract instance, and then we follow that up with some functions defined to operate over that data (or even just to act as static functions like in the case of an on-chain library).

On line 7 we see a function called init() that returns state. This is a slightly magic function, because it is the initialization function that is only called a single time to put the contract on chain for you. You can kind of think of this as the constructor for the contract instance. It is possible to clone contracts instead of create contracts on chain, and that is an optimization where the source and bytecode of the contract is re-used instead of being duplicated on chain, and merely applied to a new account instance (a new instance of its state). That saves space on-chain, and that’s important because storage on chain is precious.

We have one final function called greet(). It takes no arguments and just returns the string "Hello, World!" that we put into our state in the init() function.

Now for the interesting part…

We are going to click Deploy and a little contract call window is going to pop up. In this specific case we have nothing additional to do, so just click the Deploy button.

The title of this window is Deploy: Hello.init/0. That just means that we are deploying using the function Hello.init/0 where the 0 in the name is the arity of the function. Because it is arity 0 it has no arguments, which we can see in the Call args field. In the Return Type field we see that it will return a contract address to us. In the contract this function returns state but in practice as the person deploying the contract, what we actually want back is the address of the contract (aka its “contract ID”) so that we can interact with it later. It will be a string like "ct_blahblahblah...".

Below that we see Signature Key — this is a little drop box selector thingy so that you can pick which of your keys to sign and deploy (and pay for deployment of) the contract with. It will default to whichever key is selected in the main interface at the moment you open this contract deployment interface, but you can change it here as well.

Below that we have TX Paramters and that’s some stuff about how much money the contract’s address should start out with (that the deploying account would have to provide), maximum gas the one deploying it is willing to pay, the price in pucks of that gas, and the TTL (time to live) of the contract to start with.

Once we click Deploy we will nearly always get an intermediate state like this:

The reason for this is that the contract create transaction has to go from GajuDesk to whatever Gajumaru node it is connected to, and there be entered into the mempool until it is included in a microblock by the current chain leader (aka “mined”). If you are used to other blockchains transactions on Gajumaru might seem unreal because they are so fast that most people chuckle a little the first time they experience it.

If you just click Check Deployment Status you will be taken to the deployed contract screen.

This screen sure looks a lot like the previous one! That’s because it kind of is, the main distinction being that this view of the contract is for after it is already on chain and you might want to do something with it, like call or dry-run functions on it.

Because the greet/0 function does not alter the state of the chain at all, there is no point in actually calling the function. We just want to “dry run” the function to get the return value to verify that we can actually query a thing on a chain node and interpret the response.

So we click Dry Run next to greet/0 and are met with another contract call screen like the one we saw before to deploy:

Once again we see that we have no args to bother with, but we have a return type we actually care about this time. GajuDesk will call the chain node we’re connected to and submit a contract call dry run request to the node, get the return result, and decode it for us in the little Return Type text field.

The response that you typically care about is right there at the top in the Return Type field, but if something goes wrong, or maybe you want to know more about the transaction itself, you can check the bottom console window where the entire response is presented before any of it was interpreted by the system.

As we can see, we got the expected value "Hello, World!" back.

Yay!

Conclusion

It has never been this easy to interact with a real chain before, but now it is! Moving on from here you can go explore some Sophia docs and learn more, or just stay tuned and I’ll write a few more examples out here or on stream so you can get your feet wet(ter).

A novel aspect of the Gajumaru is that source code for contracts is actually deployed to the chain, and can be retrieved from the chain directly by FateWeaver. So you can fire off a contract deploy and then pull it from the chain, rebuild it, and have the call interface built for you all automatically without ever leaving GajuDesk.

I’ll do a few more little Sophia tutorials, will be continuing to write Sophia and Erlang on my livestreams, and be putting out quite a few utilities in the very near future. If you follow along here then the way things like GajuMarket, GajuPay, GajuExpress and so on work will be much more clear.

We’re still getting our public documentation in order, and I’ll be doing tutorial level material here until we have the official site a bit better fleshed out.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.