Skip to content

Contract Query Snippets

Interactive Demo

Results will appear here...

Table of Contents

Setup

Import and Client Setup

import { createPublicClient, http } from 'viem';
import { base } from 'viem/chains';
 
const AUX_ADDRESS = '0x40AB9b5299BBd50B802396cd6a107f51Cd3b5001';
 
const client = createPublicClient({
  chain: base,
  transport: http('https://mainnet.base.org')
});

Full ABI Definition

const auxAbi = [
  {
    name: 'getTopLink',
    type: 'function',
    stateMutability: 'view',
    inputs: [],
    outputs: [{ name: '', type: 'tuple', components: [
      { name: 'author', type: 'address' },
      { name: 'votes', type: 'int256' },
      { name: 'timestamp', type: 'uint256' },
      { name: 'winner', type: 'bool' },
      { name: 'url', type: 'string' },
      { name: 'postType', type: 'uint8' }
    ]}]
  },
  {
    name: 'getLink',
    type: 'function',
    stateMutability: 'view',
    inputs: [{ name: '_linkId', type: 'uint256' }],
    outputs: [{ name: '', type: 'tuple', components: [
      { name: 'author', type: 'address' },
      { name: 'votes', type: 'int256' },
      { name: 'timestamp', type: 'uint256' },
      { name: 'winner', type: 'bool' },
      { name: 'url', type: 'string' },
      { name: 'postType', type: 'uint8' }
    ]}]
  },
  {
    name: 'getLinkVotes',
    type: 'function',
    stateMutability: 'view',
    inputs: [{ name: '_linkId', type: 'uint256' }],
    outputs: [{ name: '', type: 'int256' }]
  },
  {
    name: 'getBatchLinkVotes',
    type: 'function',
    stateMutability: 'view',
    inputs: [{ name: '_linkIds', type: 'uint256[]' }],
    outputs: [{ name: '', type: 'int256[]' }]
  },
  {
    name: 'hasVotedOnLink',
    type: 'function',
    stateMutability: 'view',
    inputs: [
      { name: '_linkId', type: 'uint256' },
      { name: '_address', type: 'address' }
    ],
    outputs: [{ name: '', type: 'bool' }]
  },
  {
    name: 'getUserActivity',
    type: 'function',
    stateMutability: 'view',
    inputs: [{ name: 'user', type: 'address' }],
    outputs: [
      { name: 'lastPostTime', type: 'uint256' },
      { name: 'lastVoteTime', type: 'uint256' },
      { name: 'totalPosts', type: 'uint256' },
      { name: 'totalVotes', type: 'uint256' }
    ]
  },
  {
    name: 'canPost',
    type: 'function',
    stateMutability: 'view',
    inputs: [{ name: '_user', type: 'address' }],
    outputs: [{ name: '', type: 'bool' }]
  },
  {
    name: 'linkCount',
    type: 'function',
    stateMutability: 'view',
    inputs: [],
    outputs: [{ name: '', type: 'uint256' }]
  },
  {
    name: 'LINK_COST',
    type: 'function',
    stateMutability: 'view',
    inputs: [],
    outputs: [{ name: '', type: 'uint256' }]
  },
  {
    name: 'VOTE_COST',
    type: 'function',
    stateMutability: 'view',
    inputs: [],
    outputs: [{ name: '', type: 'uint256' }]
  },
  {
    name: 'COOLDOWN',
    type: 'function',
    stateMutability: 'view',
    inputs: [],
    outputs: [{ name: '', type: 'uint256' }]
  },
  {
    name: 'URL_REUSE_COOLDOWN',
    type: 'function',
    stateMutability: 'view',
    inputs: [],
    outputs: [{ name: '', type: 'uint256' }]
  },
  {
    name: 'LinkCreated',
    type: 'event',
    inputs: [
      { name: 'id', type: 'uint256', indexed: true },
      { name: 'link', type: 'tuple', indexed: false, components: [
        { name: 'author', type: 'address' },
        { name: 'votes', type: 'int256' },
        { name: 'timestamp', type: 'uint256' },
        { name: 'winner', type: 'bool' },
        { name: 'url', type: 'string' },
        { name: 'postType', type: 'uint8' }
      ]}
    ]
  },
  {
    name: 'Voted',
    type: 'event',
    inputs: [
      { name: 'id', type: 'uint256', indexed: true },
      { name: 'link', type: 'tuple', indexed: false, components: [
        { name: 'author', type: 'address' },
        { name: 'votes', type: 'int256' },
        { name: 'timestamp', type: 'uint256' },
        { name: 'winner', type: 'bool' },
        { name: 'url', type: 'string' },
        { name: 'postType', type: 'uint8' }
      ]},
      { name: 'voter', type: 'address', indexed: true }
    ]
  },
  {
    name: 'NewTopLink',
    type: 'event',
    inputs: [
      { name: 'link', type: 'tuple', indexed: false, components: [
        { name: 'author', type: 'address' },
        { name: 'votes', type: 'int256' },
        { name: 'timestamp', type: 'uint256' },
        { name: 'winner', type: 'bool' },
        { name: 'url', type: 'string' },
        { name: 'postType', type: 'uint8' }
      ]}
    ]
  }
] as const;

Query Functions

Get Total Link Count

const count = await client.readContract({
  address: AUX_ADDRESS,
  abi: auxAbi,
  functionName: 'linkCount'
});
console.log('Total links:', count.toString());

Get Link by ID

const linkId = 0n;
 
const link = await client.readContract({
  address: AUX_ADDRESS,
  abi: auxAbi,
  functionName: 'getLink',
  args: [linkId]
});
 
console.log('Link:', {
  author: link.author,
  votes: link.votes.toString(),
  timestamp: new Date(Number(link.timestamp) * 1000),
  winner: link.winner,
  url: link.url,
  postType: ['link', 'image', 'video', 'audio', 'text', 'other'][link.postType]
});

Get Current Top Link

const topLink = await client.readContract({
  address: AUX_ADDRESS,
  abi: auxAbi,
  functionName: 'getTopLink'
});
 
console.log('Top Link:', {
  author: topLink.author,
  votes: topLink.votes.toString(),
  url: topLink.url,
  winner: topLink.winner
});

Get Random Link

// First get total link count
const totalLinks = await client.readContract({
  address: AUX_ADDRESS,
  abi: auxAbi,
  functionName: 'linkCount'
});
 
// Generate random link ID (0 to totalLinks - 1)
const randomId = BigInt(Math.floor(Math.random() * Number(totalLinks)));
 
// Fetch the random link
const randomLink = await client.readContract({
  address: AUX_ADDRESS,
  abi: auxAbi,
  functionName: 'getLink',
  args: [randomId]
});
 
console.log('Random Link (ID: ' + randomId + '):', {
  author: randomLink.author,
  votes: randomLink.votes.toString(),
  timestamp: new Date(Number(randomLink.timestamp) * 1000),
  winner: randomLink.winner,
  url: randomLink.url,
  postType: ['link', 'image', 'video', 'audio', 'text', 'other'][randomLink.postType]
});

Get Vote Count for a Link

const linkId = 0n;
 
const votes = await client.readContract({
  address: AUX_ADDRESS,
  abi: auxAbi,
  functionName: 'getLinkVotes',
  args: [linkId]
});
 
console.log('Votes:', votes.toString());

Get Batch Link Votes

const linkIds = [0n, 1n, 2n];
 
const votes = await client.readContract({
  address: AUX_ADDRESS,
  abi: auxAbi,
  functionName: 'getBatchLinkVotes',
  args: [linkIds]
});
 
votes.forEach((v, i) => {
  console.log('Link ' + linkIds[i] + ': ' + v.toString() + ' votes');
});

Check if Address Voted on Link

const linkId = 0n;
const userAddress = '0x...';
 
const hasVoted = await client.readContract({
  address: AUX_ADDRESS,
  abi: auxAbi,
  functionName: 'hasVotedOnLink',
  args: [linkId, userAddress]
});
 
console.log('Has voted:', hasVoted);

Get User Activity

const userAddress = '0x...';
 
const [lastPostTime, lastVoteTime, totalPosts, totalVotes] = await client.readContract({
  address: AUX_ADDRESS,
  abi: auxAbi,
  functionName: 'getUserActivity',
  args: [userAddress]
});
 
console.log('User Activity:', {
  lastPostTime: new Date(Number(lastPostTime) * 1000),
  lastVoteTime: new Date(Number(lastVoteTime) * 1000),
  totalPosts: totalPosts.toString(),
  totalVotes: totalVotes.toString()
});

Check if User Can Post

const userAddress = '0x...';
 
const canPost = await client.readContract({
  address: AUX_ADDRESS,
  abi: auxAbi,
  functionName: 'canPost',
  args: [userAddress]
});
 
console.log('Can post:', canPost);

Get Contract Parameters

const [linkCost, voteCost, cooldown, urlCooldown] = await Promise.all([
  client.readContract({ address: AUX_ADDRESS, abi: auxAbi, functionName: 'LINK_COST' }),
  client.readContract({ address: AUX_ADDRESS, abi: auxAbi, functionName: 'VOTE_COST' }),
  client.readContract({ address: AUX_ADDRESS, abi: auxAbi, functionName: 'COOLDOWN' }),
  client.readContract({ address: AUX_ADDRESS, abi: auxAbi, functionName: 'URL_REUSE_COOLDOWN' })
]);
 
console.log('Contract Parameters:', {
  linkCost: (linkCost / 10n**18n) + ' ATTN',
  voteCost: (voteCost / 10n**18n) + ' ATTN',
  cooldown: cooldown + ' seconds',
  urlReuseCooldown: (urlCooldown / 3600n) + ' hours'
});

Fetch Multiple Links

const linkIds = Array.from({ length: 10 }, (_, i) => BigInt(i));
 
const links = await Promise.all(
  linkIds.map(id =>
    client.readContract({
      address: AUX_ADDRESS,
      abi: auxAbi,
      functionName: 'getLink',
      args: [id]
    }).catch(() => null)
  )
);
 
const validLinks = links
  .map((link, i) => link ? { id: i, ...link } : null)
  .filter(Boolean);
 
console.log('Links:', validLinks);

Event Logs

Get Recent Link Creations

const currentBlock = await client.getBlockNumber();
 
const logs = await client.getLogs({
  address: AUX_ADDRESS,
  event: auxAbi.find(e => e.name === 'LinkCreated'),
  fromBlock: currentBlock - 1000n,
  toBlock: currentBlock
});
 
logs.forEach(log => {
  console.log('New Link:', {
    id: log.args.id.toString(),
    author: log.args.link.author,
    url: log.args.link.url,
    timestamp: new Date(Number(log.args.link.timestamp) * 1000),
    blockNumber: log.blockNumber
  });
});

Get Recent Votes

const currentBlock = await client.getBlockNumber();
 
const logs = await client.getLogs({
  address: AUX_ADDRESS,
  event: auxAbi.find(e => e.name === 'Voted'),
  fromBlock: currentBlock - 1000n,
  toBlock: currentBlock
});
 
logs.forEach(log => {
  console.log('Vote:', {
    linkId: log.args.id.toString(),
    voter: log.args.voter,
    currentVotes: log.args.link.votes.toString(),
    blockNumber: log.blockNumber
  });
});

Get Votes for Specific Link

const linkId = 0n;
 
const logs = await client.getLogs({
  address: AUX_ADDRESS,
  event: auxAbi.find(e => e.name === 'Voted'),
  args: { id: linkId },
  fromBlock: 0n,
  toBlock: 'latest'
});
 
console.log('Found ' + logs.length + ' votes for link ' + linkId);
logs.forEach(log => {
  console.log('Voter:', log.args.voter);
});

Live Watching

Watch Links (Live)

const unwatch = client.watchContractEvent({
  address: AUX_ADDRESS,
  abi: auxAbi,
  eventName: 'LinkCreated',
  onLogs: (logs) => {
    logs.forEach(log => {
      console.log('New link created!', {
        id: log.args.id.toString(),
        author: log.args.link.author,
        url: log.args.link.url
      });
    });
  }
});
 
// To stop watching: unwatch();

Watch Votes (Live)

const unwatch = client.watchContractEvent({
  address: AUX_ADDRESS,
  abi: auxAbi,
  eventName: 'Voted',
  onLogs: (logs) => {
    logs.forEach(log => {
      console.log('New vote!', {
        linkId: log.args.id.toString(),
        voter: log.args.voter,
        totalVotes: log.args.link.votes.toString()
      });
    });
  }
});
 
// To stop watching: unwatch();

Watch New Top Link (Live)

const unwatch = client.watchContractEvent({
  address: AUX_ADDRESS,
  abi: auxAbi,
  eventName: 'NewTopLink',
  onLogs: (logs) => {
    logs.forEach(log => {
      console.log('New top link!', {
        author: log.args.link.author,
        votes: log.args.link.votes.toString(),
        url: log.args.link.url,
        timestamp: new Date(Number(log.args.link.timestamp) * 1000),
        postType: ['link', 'image', 'video', 'audio', 'text', 'other'][log.args.link.postType]
      });
    });
  }
});
 
// To stop watching: unwatch();