P1: Decentralized AI Prompt Shop: Building the Future of AI with ChatGPT-based Perplexity.ai

Empowering AI Enthusiasts to Create Custom AI Solutions Using Decentralized Smart Contracts Even If You Are Not a Developer.

Intro

Are you tired of relying on centralized AI prompt providers and their limited offerings? Isn’t it desirable if you can buy any prompts without worrying about censorship? Look no further than Perplexity.ai, the revolutionary platform that tailors ChatGPT in a way that creates decentralized AI prompt shops more reliably (not affiliated to them, although they should invite me, because I have such great ideas that involve them).

Welcome to the first article of a new series. I will talk about how to build and improve this shop with the help of this latest IT breakthrough.

Previously, I released a tutorial series about how to do decentralized crowdfunding with smart contracts. You can read them starting from the first article. We will use the fund and contributors’ accounts collected from there on this project.

While building that part of the project is optional and you can delegate the crowdfunding part to a partner, doing so allows you to claim the title of creator. This title serves as recognition for your contributions to the project’s development and grants you respect within the community. Additionally, if you are good enough so that community loves you so much, you can earn some tokens as compensation for your work, which you can use to further your involvement in the network.

As a result, we will have 100 Eth, or the equivalent of it depending on how you modify it, to start our project here.

What is a Decentralized AI Prompt Shop?

A decentralized AI prompt marketplace allows users to purchase custom AI prompts for execution by models such as ChatGPT and its competitors. The platform leverages smart contracts on the Ethereum blockchain or its derivatives, such as Polygon or Avalanche, empowering users to buy their preferred prompts in a censorship-resistant way.

These prompts have a wide range of applications, including generating text and images, answering questions, and more. Participants from around the world compete to create the best version of each prompt, with the incentive of earning payment in the form of a token designed to appreciate in Ethereum value. For example, if we design it in a way that askers pay in Eth and the contract’s economy runs on a limited-supply token system, people will buy and hodl this system’s tokens, because as those who need working prompts put in Eth in exchange for prompts, the token will be worth more and more of the coin of the hosting network. And subsequently, if the answerers are paid in tokens, their compliments will be worth more than the askers pay, and more so if they also hodl.

By designing the token mechanism to incentivize high-quality output, the platform ensures that users receive the desired product. Ultimately, the decentralized nature of the marketplace provides a level playing field for participants worldwide to contribute to the development of magical ways of using the cutting-edge AI technology and also let them understand how it works with the code open sourced on the network so your project is impeccable, meanwhile it is also almost impossible to copy your success, because the community has glued to you, which requires time your copiers don’t often have.

What your community looks like with you the creator and your project in the center

Building the Decentralized AI Prompt Shop with Perplexity.ai

Why Perplexity.ai? It’s a ChatGPT backed search engine that gives answers in natural language and helps you produce the code out right. We use it rather than the leading chat bot itself because Perplexity.ai has successfully tailored it in a way that you can verify the result, so whenever there is a bug, you can open the source and check the original words. And this bot even knows what the authoritative sources are for your specific topics.

With Perplexity.ai, building a decentralized AI prompt shop is easier than ever. Simply ask Perplexity.ai to generate the Solidity smart contract code that fits your specific requirements, and you’ll be on your way to creating your own custom AI prompt shop. Let’s take a look at an example of how to create a Solidity smart contract for this Q&A system.

Go to Perplexity.ai, sign up with Google (if you haven’t yet), log in, and type:

Write a solidity smart contract that takes 100 eth to start, creates a token, allow questions and answers, store them, require paying 0.001 eth to ask and pays 10 tokens for answers with majority of votes from designated accounts

And just like that, Perplexity.ai will provide you with the Solidity code you need to build your own Q&A system.

Here’s a Solidity smart contract that takes 100 ETH to start, creates a token, allows questions and answers, stores them, requires paying 0.001 ETH to ask, and pays 10 tokens for answers with the majority of votes from designated accounts:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract QAToken {
string public name;
string public symbol;
uint8 public decimals;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;

event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);

constructor() payable {
require(msg.value == 100 ether, "100 ether required to start");
name = "QAToken";
symbol = "QA";
decimals = 18;
totalSupply = 1000000 * 10 ** uint256(decimals);
balanceOf[msg.sender] = totalSupply;
emit Transfer(address(0), msg.sender, totalSupply);
}

function askQuestion(string memory question) payable public {
require(msg.value == 0.001 ether, "0.001 ether required to ask a question");
// store the question
}

function answerQuestion(uint256 questionId, string memory answer) public {
// store the answer
}

function voteForAnswer(uint256 questionId, uint256 answerId) public {
// vote for the answer
}

function payAnswer(uint256 questionId, uint256 answerId) public {
// check if the answer has the majority of votes from designated accounts
// if yes, pay 10 tokens to the answerer
}
}

This smart contract creates a QAToken with a name “QAToken” and a symbol “QA”. It requires 100 ETH to be sent to the contract upon deployment. The contract also has functions to ask a question, answer a question, vote for an answer, and pay for an answer. The askQuestion() function requires the sender to pay 0.001 ETH to ask a question. The answerQuestion() function allows anyone to answer a question by providing the question ID and the answer. The voteForAnswer() function allows anyone to vote for an answer by providing the question ID and the answer ID. The payAnswer() function checks if the answer has the majority of votes from designated accounts and pays 10 tokens to the answerer if the condition is met. Note that this is just a basic example and you will need to modify the code to fit your specific requirements.

1. codemotion, 2. ethereum, 3. korakbhaduri, 4. stackexchange, 5. stackoverflow

The “designated accounts” are the contributors’ addresses from the contract you or your partner create as well as the asker’s address.

Let’s dive into it.

Storing Questions and Answers

The key to any Q&A system is the ability to store questions and answers. With Perplexity.ai, storing questions and answers is as simple as adding a few lines of code to your Solidity smart contract based on the bot’s hints. You can store questions and answers in a variety of ways, from a simple array to a more complex database.

Here, Perplexity.ai has hinted you with comments

// store the question

and

// store the answer

This is because there is a cap on the AI’s output length. But this is not a problem at all. Why? Yes! We always can ask follow-up questions:

how to implement “// store the question”

And the answer is:

To store a question in a Solidity smart contract, you can use a mapping data structure. A mapping is a key-value store that allows you to associate a value with a unique key. In this case, you can use the question ID as the key and the question string as the value. Here’s an example of how to store a question using a mapping:

contract QAToken {
mapping(uint256 => string) public questions;

function askQuestion(uint256 questionId, string memory question) payable public {
require(msg.value == 0.001 ether, "0.001 ether required to ask a question");
questions[questionId] = question;
}
}

In this example, the questions mapping is declared at the contract level with a key of type uint256 and a value of type string. The askQuestion() function takes a questionId and a question string as arguments and stores the question in the questions mapping using the questionId as the key. Note that this is just a basic example and you will need to modify the code to fit your specific requirements.

1. stackoverflow, 2. stackexchange, 3. soliditylang, 4. stackoverflow, 5. geeksforgeeks

So, the AI wants the user to know the “questionID”, which is impossible. They just use the product.

That’s when our human minds shine:

can “questionId” be automatically determined instead

we ask.

Yes, you can automatically determine the questionId instead of requiring the user to provide it. One way to do this is to use a state variable to keep track of the current question ID and increment it every time a new question is asked. Here's an example:

contract QAToken {
uint256 public currentQuestionId;
mapping(uint256 => string) public questions;

constructor() payable {
require(msg.value == 100 ether, "100 ether required to start");
currentQuestionId = 1;
// other initialization code
}

function askQuestion(string memory question) payable public {
require(msg.value == 0.001 ether, "0.001 ether required to ask a question");
questions[currentQuestionId] = question;
currentQuestionId++;
}

// other functions
}

In this example, the currentQuestionId state variable is initialized to 1 in the constructor. The askQuestion() function stores the question using the current value of currentQuestionId as the key and then increments it. This way, each new question will automatically get a unique ID.

Note that you may want to add additional checks to ensure that the currentQuestionId doesn't overflow or collide with existing question IDs.

1. stackoverflow, 2. soliditylang, 3. stackexchange, 4. geeksforgeeks, 5. soliditylang

Just like that, the problem is solved. Isn’t it amazing?

We’ll deal with the “overflow” problem later on.

Likewise:

how to “// store the answer” that can refer to their linked questions

In a fraction of a second, the bot says:

To store an answer that can refer to its linked question, you can use a mapping to associate each answer with its question ID. Here’s an example:

contract QAToken {
uint256 public currentQuestionId;
uint256 public currentAnswerId;
mapping(uint256 => string) public questions;
mapping(uint256 => mapping(uint256 => string)) public answers;

constructor() payable {
require(msg.value == 100 ether, "100 ether required to start");
currentQuestionId = 1;
currentAnswerId = 1;
// other initialization code
}

function askQuestion(string memory question) payable public {
require(msg.value == 0.001 ether, "0.001 ether required to ask a question");
questions[currentQuestionId] = question;
currentQuestionId++;
}

function answerQuestion(uint256 questionId, string memory answer) public {
answers[questionId][currentAnswerId] = answer;
currentAnswerId++;
}

// other functions
}

In this example, the answers mapping is a nested mapping that associates each question ID with another mapping that associates each answer ID with an answer string. The answerQuestion() function takes a questionId and an answer string as arguments and stores the answer in the answers mapping using the questionId as the outer key and the currentAnswerId as the inner key. The currentAnswerId is then incremented so that the next answer will get a unique ID. Note that this is just a basic example and you will need to modify the code to fit your specific requirements.

1. stackoverflow, 2. soliditylang, 3. stackoverflow, 4. stackexchange, 5. alchemy

Voting for Answers

In order to ensure the quality of answers, it’s important to have a mechanism for users to vote for the best answer. Perplexity.ai gave us the pseudo code to hint us to continue asking:

function payAnswer(uint256 questionId, uint256 answerId) public {
// check if the answer has the majority of votes from designated accounts
// if yes, pay 10 tokens to the answerer
}

The idea is that the payAnswer() function checks if the answer has the majority of votes from designated accounts and pays 10 tokens to the answerer if the condition is met. So:

how to let designated accounts “// vote for the answer”

Perplexity.ai answers you:

To let designated accounts vote for an answer, you can use a mapping to keep track of which accounts have voted for which answers. Here’s an example:

contract QAToken {
uint256 public currentQuestionId;
uint256 public currentAnswerId;
mapping(uint256 => string) public questions;
mapping(uint256 => mapping(uint256 => string)) public answers;
mapping(uint256 => mapping(address => bool)) public votes;

constructor() payable {
require(msg.value == 100 ether, "100 ether required to start");
currentQuestionId = 1;
currentAnswerId = 1;
// other initialization code
}

function askQuestion(string memory question) payable public {
require(msg.value == 0.001 ether, "0.001 ether required to ask a question");
questions[currentQuestionId] = question;
currentQuestionId++;
}

function answerQuestion(uint256 questionId, string memory answer) public {
answers[questionId][currentAnswerId] = answer;
currentAnswerId++;
}

function voteForAnswer(uint256 questionId, uint256 answerId) public {
require(/* check if the sender is a designated account */);
require(!votes[questionId][msg.sender], "already voted");
votes[questionId][msg.sender] = true;
}

// other functions
}

In this example, the votes mapping is a nested mapping that associates each question ID with another mapping that associates each address with a boolean indicating whether they have voted for that question. The voteForAnswer() function takes a questionId and an answerId as arguments and checks if the sender is a designated account and if they have not already voted for that question. If both conditions are met, the function sets the corresponding value in the votes mapping to true. Note that you will need to modify the code to fit your specific requirements, such as defining the designated accounts and checking if the sender is one of them.

1. stackexchange, 2. stackoverflow, 3. stackexchange, 4. github, 5. stackoverflow

Great. So, now the idea is to have the voting function “voteForAnswer” to check if the sender is a contributor/answerer/asker (depending on which group of people you as a creator want to vote on), and then check if the designated account has voted. Only such an account with privilege that has never voted can vote an answer to a question once.

Then let’s tackle the last pseudo code:

how to store and “check if the sender is a designated account”

I also asked how to store the account because once the account has interacted with the contract, it should store it.

The way to do that is:

To store and check if the sender is a designated account, you can use a mapping to associate each address with a boolean indicating whether they are a designated account. Here’s an example:

contract QAToken {
uint256 public currentQuestionId;
uint256 public currentAnswerId;
mapping(uint256 => string) public questions;
mapping(uint256 => mapping(uint256 => string)) public answers;
mapping(address => bool) public designatedAccounts;
mapping(uint256 => mapping(address => bool)) public votes;

constructor() payable {
require(msg.value == 100 ether, "100 ether required to start");
currentQuestionId = 1;
currentAnswerId = 1;
// other initialization code
}

function askQuestion(string memory question) payable public {
require(msg.value == 0.001 ether, "0.001 ether required to ask a question");
questions[currentQuestionId] = question;
currentQuestionId++;
}

function answerQuestion(uint256 questionId, string memory answer) public {
answers[questionId][currentAnswerId] = answer;
currentAnswerId++;
}

function addDesignatedAccount(address account) public {
require(/* check if the sender is authorized to add designated accounts */);
designatedAccounts[account] = true;
}

function removeDesignatedAccount(address account) public {
require(/* check if the sender is authorized to remove designated accounts */);
designatedAccounts[account] = false;
}

function voteForAnswer(uint256 questionId, uint256 answerId) public {
require(designatedAccounts[msg.sender], "not authorized");
require(!votes[questionId][msg.sender], "already voted");
votes[questionId][msg.sender] = true;
}

// other functions
}

In this example, the designatedAccounts mapping associates each address with a boolean indicating whether they are a designated account. The addDesignatedAccount() and removeDesignatedAccount() functions allow authorized accounts to add or remove designated accounts from the mapping. The voteForAnswer() function checks if the sender is a designated account and if they have not already voted for that question. If both conditions are met, the function sets the corresponding value in the votes mapping to true.

Note that you will need to modify the code to fit your specific requirements, such as defining the authorized accounts and checking if the sender is one of them.

1. stackexchange, 2. stackoverflow, 3. stackoverflow, 4. stackexchange, 5. consensys

It turns out that a simple question “how to check if the sender is a designated account” can do the job. You don’t need “addDesignatedAccount” or “removeDesignatedAccount” because you wouldn’t want any random account to add or remove the privileged accounts. I’ll leave this fun experiment to you.

Success

Yay! We have our embryonic form of the decentralized AI-prompt shop.

Conclusion

In conclusion, Perplexity.ai is a game-changing platform that empowers AI enthusiasts and developers to create their own custom AI solutions using decentralized smart contracts. By leveraging the power of the Ethereum blockchain, users can build decentralized AI prompt shops that enable the execution of AI prompts by models such as ChatGPT and its competitors. With Perplexity.ai, the future of AI is decentralized and customizable.

Now, anyone can ask anything without worrying about any self-serving “public servant” frowning upon them.

But there are many unsolved issues:

  • Where to test it?
  • How to test it?
  • How to enable negotiation between contributors?
  • How to make it fair?
  • How to launch it on a test net?
  • How to launch it on mainnet?
  • How to market it? How to form a community?

If you are interested in this stuff, click that “follow” button and smart the “clap” button, so that you won’t miss the next article when I release it. This will also allow this content to show on more people’s screens which will help you with the community building in advance.

If you want to ask anything, don’t be shy, just ask in the comment. I will try to answer you as much as I can.

I hope to see you in the next article!

Disclaimer

I’m only sharing how insanely possible it is to create DeFi with AI. I don’t know your specific personal situations, so I can’t make tailored ideas for you. So, you will need to customize the knowledge here your way and make multiple attempts to succeed without guarantee that you will, because you have to be persistent, find what personal factors causes you to fail, and know how to fix them.

That being said, you can leave a message in the comment for help.

--

--

ChainGPT
𝐀𝐈 𝐦𝐨𝐧𝐤𝐬.𝐢𝐨

Building web3 apps and smart contracts with AI? Follow me! I'll show you how to find the right AI for the right tasks, and use them right.