Non Fungible Tokens - NFTs
To create a smart contract that will carry an NFT, have your smart contract extend the OrdinalNFT
class:
import { method, prop, assert, ByteString, sha256, Sha256 } from "scrypt-ts";
import { OrdinalNFT } from "scrypt-ord";
export class HashLockNFT extends OrdinalNFT {
@prop()
hash: Sha256;
constructor(hash: Sha256) {
super();
// Important: Call `init` after the `super()` statement.
this.init(...arguments);
this.hash = hash;
}
@method()
public unlock(message: ByteString) {
assert(this.hash === sha256(message), "hashes are not equal");
}
}
The contract above represents an NFT that can be unlocked / transferred by providing the secret pre-image of a hash value.
Each constructor extending the OrdinalNFT
class must also call the instances init
method and pass the constructors arguments. It is important to call this function after the call to super
.
Inscribe
The following code demonstrates how deploy / inscribe the NFT contract:
HashLockNFT.loadArtifact();
const text = "Hello sCrypt and 1Sat Ordinals";
const message = toByteString('secret string', true);
const hash = sha256(message);
const instance = new HashLockNFT(hash);
const signer = getDefaultSigner();
await instance.connect(signer);
const inscriptionTx = await instance.inscribeText(text);
console.log("Inscribed NFT: ", inscriptionTx.id);
The inscribeText
first inscribes the locking script with the specified text and then deploys the contract.
Among text the inscription can contain many other types of data. Here's how you can conveniently inscribe an image:
// ...
const bb = readFileSync(join(__dirname, "..", "..", "logo.png")).toString("base64");
const tx = await instance.inscribeImage(bb, ContentType.PNG);
console.log("Inscribed NFT: ", tx.id);
In fact the data type can be arbitrary. It only depends on the Ordinals wallet you're using to support that data type.
const tx = await instance.inscribe({
content: `your content in hex`,
contentType: `your contentType`,
});
console.log("Inscribed NFT: ", tx.id);
The value contentType
must be a MIME-type string. The ContentType
object contains common MIME-types.
Transfer
You can easily transfer a deployed NFT to an Ordinals address by passing a transfer
value via the method call parameters.
OrdiNFTP2PKH
is a P2PKH contract for holding ordinals NFTs. Like a normal P2PKH contract, you need an address to instantiate it.
// ... deploy code from above
const { tx: transferTx } = await instance.methods.unlock(
message,
{
transfer: new OrdiNFTP2PKH(
Addr(recipientAddress.toByteString())
),
}
);
console.log("Transferred NFT: ", transferTx.id);
The transfer
parameter can be any single instance of a contract that extends OrdinalNFT
.