Development
...
Recipes
Smart Contracts
Read Contracts State
1min
As explained in Smart Contracts, the data stack has a fixed layout and can be read in 8-byte blocks. The following example shows how to read parts of a NFTSRC40 contract, which are deployed through the Signum NFT platform
This full example in the SignumJS examples folder
JS
const {Address} = require("@signumjs/core");
const {ContractDataView} = require("@signumjs/contracts");
const {Amount} = require("@signumjs/util");
/**
* This is an example of how to read data from a contract
*
* Usually, contracts maintain a certain internal state, like ownership, paid dividends or whatever
* These data is publicly accessible and can be read relatively easily using ContractDataView
* The requirement is that you know the positions of the values in the contracts data stack.
* The data stack is divided into 8 byte segments and can be addressed using indices.
*
* The following example uses parts of the layout of the NFTSRC40 contract.
*
* If you use your custom contracts, you might want to use the Contract Inspector to see you data stack
*
* https://contracts-inspector.ohager.vercel.app/
*
*/
const NftContractDataIndex = {
Owner: 0,
Status: 1,
CurrentPrice: 2,
PlatformAddress: 3,
PlatformFee: 4,
RoyaltiesFee: 5,
RoyaltiesOwner: 6,
HighestBidder: 19,
TotalTimesSold: 27,
TotalBidsReceived: 28,
TotalRoyaltiesFee: 29,
TotalPlatformFee: 30,
TotalLikes: 31,
}
// using a dedicated class for contract data view is a good practice
class NftDataView {
constructor(contract) {
this.id = contract.at;
// ContractDataView gives us easy access to the 8-byte blocks
this.view = new ContractDataView(contract);
}
getId() {
return this.id;
}
getOwnerId() {
return this.view.getVariableAsDecimal(NftContractDataIndex.Owner);
}
getRoyaltiesOwnerId() {
return this.view.getVariableAsDecimal(NftContractDataIndex.RoyaltiesOwner);
}
getPlatformId() {
return this.view.getVariableAsDecimal(NftContractDataIndex.PlatformAddress);
}
getPlatformFee() {
return parseInt(
this.view.getVariableAsDecimal(NftContractDataIndex.PlatformFee),
10
);
}
/* ... and so on, and so forth */
}
const LedgerHostUrls = {
TestNet: 'http://localhost:6876',
MainNet: 'https://europe.signum.network',
}
function asAddress(id, prefix){
return Address.fromNumericId(id, prefix).getReedSolomonAddress()
}
/**
* This advanced example shows how to interact with smart contracts, i.e. how to call methods
*/
async function showNftData({ledgerChoice, nft}) {
try {
const ledger = LedgerClientFactory.create({
nodeHost: LedgerHostUrls[ledgerType])
}
// this way we not only convert the contracts address to its id, but this method also asserts
// that we have a formally valid address. It's not guaranteed that the address really exists in the chain
const nftId = Address.create(nft).getNumericId()
const nftContract = await ledger.contract.getContract(nftId)
const explorerUrl = ledgerChoice === 'TestNet' ? `https://t-chain.signum.network/at/${nftId}` : `https://chain.signum.network/at/${nftId}`
const prefix = ledgerChoice === 'TestNet'? 'TS' : 'S'
const nftDataView = new NftDataView(nftContract)
console.info(`Stats of NFT '${asAddress(nftId, prefix)}' - ${explorerUrl}`)
console.info('----------------------------------------')
console.info('Creator:', nftContract.creatorRS)
console.info('Current Owner:', asAddress(nftDataView.getOwnerId(),prefix))
console.info('Current Price:', nftDataView.getCurrentPrice().getSigna(), 'SIGNA')
console.info('Current Status:', nftDataView.getStatus())
console.info('Number of Sales:', nftDataView.getTotalTimesSold())
console.info('Likes:', nftDataView.getTotalLikes())
} catch (e) {
console.error(e);
}
}
(async () => {
await showNftData({
ledgerChoice: 'TestNet',
nft: '5704341721881819656'
});
})();
Updated 03 Mar 2023
Did this page help you?