Docs
Contracts
You write ordinary Solidity. The source uses address, uint256, msg.sender, and block.chainid. There is no Kalyx keyword, no Kalyx type, and no extra pragma. What you set by hand is the instruction set, the way an address is shown, and the wallet that signs the deploy.
The language
A contract is one file. The wallet’s Write tab and the Contracts page both compile that file in the browser. An import line has nowhere to go. Paste the whole contract into the file.
Use a pragma the loaded compiler accepts. The wallet’s Write tab loads Solidity 0.8.26, so its sample says pragma solidity 0.8.26. The Contracts page loads Solidity 0.8.38. pragma solidity ^0.8.20 compiles on both. The compiler is a separate program and stays under its own license.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Box {
uint256 public value;
function store(uint256 next) external {
value = next;
}
}
value() is the getter Solidity writes for a public variable. store changes that variable. Deploy this, call store, then read value. That is the first proof.
The instruction set
Set the compiler’s EVM version to London. The wallet’s Write tab does this for you. Solidity 0.8.20 and later will emit the PUSH0 opcode when the version is left on the compiler’s newer default. These pages do not emit PUSH0.
The Contracts page targets Paris. Paris adds no opcode after London, so that bytecode also has no PUSH0. Shanghai and anything newer are outside what these pages produce.
A constructor with arguments can be filled in on the Contracts page. The wallet’s Write tab cannot publish a constructor that takes arguments. Give that contract an empty constructor, or deploy it from Contracts.
The Write tab refuses bytecode over 24,000 bytes. The wallet refuses contract data over 60,000 bytes. Stay inside the smaller limit when you use Write.
Addresses
An account inside the contract is 20 bytes. Solidity’s address is that width. The explorer and the wallet show the same 20 bytes as KAL and 40 hex characters. You do not put the letters KAL in the source. A function argument of type address is those 20 bytes. The Contracts page accepts a KAL address in the form and passes the 20 bytes to the call.
msg.sender is the spending account that sent the transaction. block.chainid on this testnet is 21520. One KALYX is 1018 of the integer in msg.value. The account page is the rule for the KAL label. The transaction page is the rule for the integer.
The transaction
A deploy is a type 0x2 transaction on chain 21520. It has bytecode and no recipient. A call that changes state is the same type, with the contract’s KAL address as the recipient and the function data in the data field. The fee page is how the base fee burns and the tip is paid.
The spending account signs with XMSS. A deploy spends one leaf. A call that changes state spends another. A read does not. The leaf cannot be used again. Two copies of the same wallet that both sign will break the account. The account page is that rule.
The Kalyx wallet for Chrome, Brave, or Firefox is the signer. It answers on chain 21520. It does not sign an arbitrary message, so a contract that expects a separate message signature from this wallet will not receive one. The transaction signature is the account’s signature. msg.sender is how the contract sees who sent it.
Deploy it
- Open the wallet and create a spending account, or open one you already saved. Get a little public KALYX from the faucet so the fee can be paid.
- Open Contracts on the testnet. Connect the wallet. Compile
Box. The page says the deploy spends one XMSS leaf before the wallet asks you to confirm. - Confirm in the wallet. Wait for the receipt. The new address is shown as KAL. Open it on the explorer. The explorer stores the code bytes.
- Call
storewith a number. That spends a second leaf. Then press Read onvalue. The number you stored should come back. A read does not spend a leaf.
The same deploy can start on the wallet. Choose Write, compile, then Contract, and publish. Choose Call afterward. Read asks a question. Send call spends one signature. Paste call data as hex. The Contracts page builds that data from the function’s arguments, including a KAL address.
What one successful deploy proves
A stored number proves this chain accepted that bytecode and ran those two calls. It does not prove every opcode. It does not prove ecrecover or any other elliptic-curve helper. This account does not sign with an elliptic curve, so those helpers are not how a spending account authorizes a transaction. Leave them out until a contract that calls one has been deployed and the call has succeeded.
The public node does not offer execution traces. There is no step-through debugger to attach. The receipt and the logs are the record. The explorer does not check your source against the bytecode. The code bytes on the address page are the code that ran.