Add program deployment docs (#15075)
This commit is contained in:
@ -1524,8 +1524,8 @@ pub struct CliUpgradeableProgram {
|
|||||||
pub program_id: String,
|
pub program_id: String,
|
||||||
pub programdata_address: String,
|
pub programdata_address: String,
|
||||||
pub authority: String,
|
pub authority: String,
|
||||||
pub last_upgrade_slot: u64,
|
pub last_deploy_slot: u64,
|
||||||
pub program_len: usize,
|
pub data_len: usize,
|
||||||
}
|
}
|
||||||
impl QuietDisplay for CliUpgradeableProgram {}
|
impl QuietDisplay for CliUpgradeableProgram {}
|
||||||
impl VerboseDisplay for CliUpgradeableProgram {}
|
impl VerboseDisplay for CliUpgradeableProgram {}
|
||||||
@ -1537,13 +1537,13 @@ impl fmt::Display for CliUpgradeableProgram {
|
|||||||
writeln_name_value(f, "Authority:", &self.authority)?;
|
writeln_name_value(f, "Authority:", &self.authority)?;
|
||||||
writeln_name_value(
|
writeln_name_value(
|
||||||
f,
|
f,
|
||||||
"Last Upgraded In Slot:",
|
"Last Deployed In Slot:",
|
||||||
&self.last_upgrade_slot.to_string(),
|
&self.last_deploy_slot.to_string(),
|
||||||
)?;
|
)?;
|
||||||
writeln_name_value(
|
writeln_name_value(
|
||||||
f,
|
f,
|
||||||
"Program Length:",
|
"Data Length:",
|
||||||
&format!("{:?} ({:#x?}) bytes", self.program_len, self.program_len),
|
&format!("{:?} ({:#x?}) bytes", self.data_len, self.data_len),
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -951,8 +951,8 @@ fn process_show(
|
|||||||
authority: upgrade_authority_address
|
authority: upgrade_authority_address
|
||||||
.map(|pubkey| pubkey.to_string())
|
.map(|pubkey| pubkey.to_string())
|
||||||
.unwrap_or_else(|| "none".to_string()),
|
.unwrap_or_else(|| "none".to_string()),
|
||||||
last_upgrade_slot: slot,
|
last_deploy_slot: slot,
|
||||||
program_len: programdata_account.data.len()
|
data_len: programdata_account.data.len()
|
||||||
- UpgradeableLoaderState::programdata_data_offset()?,
|
- UpgradeableLoaderState::programdata_data_offset()?,
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
|
@ -54,6 +54,7 @@ module.exports = {
|
|||||||
"cli/transfer-tokens",
|
"cli/transfer-tokens",
|
||||||
"cli/delegate-stake",
|
"cli/delegate-stake",
|
||||||
"cli/manage-stake-accounts",
|
"cli/manage-stake-accounts",
|
||||||
|
"cli/deploy-a-program",
|
||||||
"offline-signing",
|
"offline-signing",
|
||||||
"offline-signing/durable-nonce",
|
"offline-signing/durable-nonce",
|
||||||
"cli/usage",
|
"cli/usage",
|
||||||
|
@ -50,7 +50,7 @@ $ solana confirm <TX_SIGNATURE>
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
// Command
|
// Command
|
||||||
$ solana deploy <PATH>
|
$ solana program deploy <PATH>
|
||||||
|
|
||||||
// Return
|
// Return
|
||||||
<PROGRAM_ID>
|
<PROGRAM_ID>
|
||||||
|
@ -11,6 +11,7 @@ new SOL periodically to reward stakers and validators. You earn more rewards
|
|||||||
the more stake you delegate.
|
the more stake you delegate.
|
||||||
|
|
||||||
## Create a Stake Account
|
## Create a Stake Account
|
||||||
|
|
||||||
To delegate stake, you will need to transfer some tokens into a stake account.
|
To delegate stake, you will need to transfer some tokens into a stake account.
|
||||||
To create an account, you will need a keypair. Its public key will be used as
|
To create an account, you will need a keypair. Its public key will be used as
|
||||||
the [stake account address](../staking/stake-accounts.md#account-address).
|
the [stake account address](../staking/stake-accounts.md#account-address).
|
||||||
@ -61,6 +62,7 @@ Withdraw Authority: EXU95vqs93yPeCeAU7mPPu6HbRUmTFPEiGug9oCdvQ5F
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Set Stake and Withdraw Authorities
|
### Set Stake and Withdraw Authorities
|
||||||
|
|
||||||
[Stake and withdraw authorities](../staking/stake-accounts.md#understanding-account-authorities)
|
[Stake and withdraw authorities](../staking/stake-accounts.md#understanding-account-authorities)
|
||||||
can be set when creating an account via the
|
can be set when creating an account via the
|
||||||
`--stake-authority` and `--withdraw-authority` options, or afterward with the
|
`--stake-authority` and `--withdraw-authority` options, or afterward with the
|
||||||
|
217
docs/src/cli/deploy-a-program.md
Normal file
217
docs/src/cli/deploy-a-program.md
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
---
|
||||||
|
title: Deploy a Program
|
||||||
|
---
|
||||||
|
|
||||||
|
Developers can deploy on-chain [programs](terminology.md#program) (often called
|
||||||
|
smart contracts elsewhere) with the Solana tools.
|
||||||
|
|
||||||
|
To learn about developing and executing programs on Solana, start with the
|
||||||
|
[overview](developing/programming-model/overview.md) and then dig into the
|
||||||
|
details of [deployed programs](developing/deployed-programs/overview.md).
|
||||||
|
|
||||||
|
To deploy a program, use the Solana tools to interact with the on-chain loader
|
||||||
|
to:
|
||||||
|
|
||||||
|
- Initialize a program account
|
||||||
|
- Upload the program's shared object to the program account's data buffer
|
||||||
|
- Verify the uploaded program
|
||||||
|
- Finalize the program by marking the program account executable.
|
||||||
|
|
||||||
|
Once deployed, anyone can execute the program by sending transactions that
|
||||||
|
reference it to the cluster.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Deploy a program
|
||||||
|
|
||||||
|
To deploy a program, you will need the location of the program's shared object
|
||||||
|
(the program binary .so)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
solana program deploy <PROGRAM_FILEPATH>
|
||||||
|
```
|
||||||
|
|
||||||
|
Successful deployment will return the program id of the deployed program, for
|
||||||
|
example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
Program Id: 3KS2k14CmtnuVv2fvYcvdrNgC94Y11WETBpMUGgXyWZL
|
||||||
|
```
|
||||||
|
|
||||||
|
Specify the keypair in the deploy command to deploy to a specific program id:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
solana program deploy --program-id <KEYPAIR_FILEPATH> <PROGRAM_FILEPATH>
|
||||||
|
```
|
||||||
|
|
||||||
|
If the program id is not specified on the command line the tools will first look
|
||||||
|
for a keypair file matching the `<PROGRAM_FILEPATH>`, or internally generate a
|
||||||
|
new keypair.
|
||||||
|
|
||||||
|
A matching program/keypair file is generated automatically by the program build
|
||||||
|
tools and looks like:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./path-to-program/program.so
|
||||||
|
./path-to-program/program-keypair.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Showing a program account
|
||||||
|
|
||||||
|
To get information about a deployed program:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
solana show <ACCOUNT_ADDRESS>
|
||||||
|
```
|
||||||
|
|
||||||
|
An example output looks like:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
Program Id: 3KS2k14CmtnuVv2fvYcvdrNgC94Y11WETBpMUGgXyWZL
|
||||||
|
ProgramData Address: EHsACWBhgmw8iq5dmUZzTA1esRqcTognhKNHUkPi4q4g
|
||||||
|
Authority: FwoGJNUaJN2zfVEex9BB11Dqb3NJKy3e9oY3KTh9XzCU
|
||||||
|
Last Upgraded In Slot: 63890568
|
||||||
|
Program Length: 5216 (0x1460) bytes
|
||||||
|
```
|
||||||
|
|
||||||
|
- `Program Id` is the address that can be referenced in an instruction's
|
||||||
|
`program_id` field when invoking a program.
|
||||||
|
- `ProgramData Address` is the account associated with the program account that
|
||||||
|
holds the program's data (shared object).
|
||||||
|
- `Authority` is the program's upgrade authority.
|
||||||
|
- `Last Deployed In Slot` is the slot in which the program was last deployed.
|
||||||
|
- `Data Length` is the size of the space reserved for deployments. The actual
|
||||||
|
space used by the currently deployed program may be less.
|
||||||
|
|
||||||
|
### Redeploy a program
|
||||||
|
|
||||||
|
A program can be redeployed to the same address to facilitate rapid development,
|
||||||
|
bug fixes, or upgrades. Matching keypair files are generated once so that
|
||||||
|
redeployments will be to the same program address.
|
||||||
|
|
||||||
|
The command looks the same as the deployment command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
solana program deploy <PROGRAM_FILEPATH>
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, programs are deployed to accounts that are twice the size of the
|
||||||
|
original deployment. Doing so leaves room for further redeployments. But, if
|
||||||
|
the initially deployed program is very small (like a simple helloworld program)
|
||||||
|
and then later grows substantially, the redeployment may fail. To avoid this,
|
||||||
|
specify a `max_len` that is at least the size (in bytes) that the program is
|
||||||
|
expected to become (plus some wiggle room).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
solana program deploy --max-len 200000 <PROGRAM_FILEPATH>
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that program accounts are required to be
|
||||||
|
[rent-excempt](developing/programming-model/accounts.md#rent-exemption), and the
|
||||||
|
`max-len` is fixed after initial deployment, so any SOL in the program accounts
|
||||||
|
is locked up permanently.
|
||||||
|
|
||||||
|
### Set a program's upgrade authority
|
||||||
|
|
||||||
|
The program's upgrade authority must to be present to deploy a program. If no
|
||||||
|
authority is specified during program deployment, the default keypair is used as
|
||||||
|
the authority. This is why redeploying a program in the steps above didn't
|
||||||
|
require an authority to be explicitly specified.
|
||||||
|
|
||||||
|
The authority can be specified during deployment:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
solana program deploy --upgrade-authority <UPGRADE_AUTHORITY_SIGNER> <PROGRAM_FILEPATH>
|
||||||
|
```
|
||||||
|
|
||||||
|
Or after deployment and using the default keypair as the current authority:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
solana program set-upgrade-authority <PROGRAM_ADDRESS> --new-upgrade-authority <NEW_UPGRADE_AUTHORITY>
|
||||||
|
```
|
||||||
|
|
||||||
|
Or after deployment and specifying the current authority:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
solana program set-upgrade-authority <PROGRAM_ADDRESS> --upgrade-authority <UPGRADE_AUTHORITY_SIGNER> --new-upgrade-authority <NEW_UPGRADE_AUTHORITY>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Immutable programs
|
||||||
|
|
||||||
|
A program can be marked immutable, which prevents all further redeployments by
|
||||||
|
specifying the `--final` flag during deployment:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
solana program deploy <PROGRAM_FILEPATH> --final
|
||||||
|
```
|
||||||
|
|
||||||
|
Or anytime after:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
solana program set-upgrade-authority <PROGRAM_ADDRESS> --final
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dumping a program to a file
|
||||||
|
|
||||||
|
The deployed program may be dumped back to a local file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
solana program dump <ACCOUNT_ADDRESS> <OUTPUT_FILEPATH>
|
||||||
|
```
|
||||||
|
|
||||||
|
The dumped file will be in the same as what was deployed, so in the case of a
|
||||||
|
shared object, the dumped file will be a fully functional shared object. Note
|
||||||
|
that the `dump` command dumps the entire data space, which means the output file
|
||||||
|
will have trailing zeros after the shared object's data up to `max_len`.
|
||||||
|
Sometimes it is useful to dump and compare a program to ensure it matches a
|
||||||
|
known program binary. The original program file can be zero-extended, hashed,
|
||||||
|
and compared to the hash of the dumped file.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ solana dump <ACCOUNT_ADDRESS> dump.so
|
||||||
|
$ cp original.so extended.so
|
||||||
|
$ truncate -r dump.so extended.so
|
||||||
|
$ sha256sum extended.so dump.so
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using an intermediary Buffer account
|
||||||
|
|
||||||
|
Instead of deploying directly to the program account, the program can be written
|
||||||
|
to an intermediary buffer account. Doing so can be useful for things like
|
||||||
|
multi-entity governed programs.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
solana progrma write-buffer <PROGRAM_FILEPATH>
|
||||||
|
```
|
||||||
|
|
||||||
|
Buffer accounts support authorities like program accounts:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
solana program set-buffer-authority <BUFFER_ADDRESS> --new-upgrade-authority <NEW_UPGRADE_AUTHORITY>
|
||||||
|
```
|
||||||
|
|
||||||
|
One exception is that buffer accounts cannot be marked immutable like program
|
||||||
|
accounts can, so they don't support `--final`.
|
||||||
|
|
||||||
|
The buffer account, once entirely written, can be passed to `deploy` to deploy
|
||||||
|
the program:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
solana program deploy --program-id <PROGRAM_ADDRESS> --buffer <BUFFER_ADDRESS>
|
||||||
|
```
|
||||||
|
|
||||||
|
Note, the buffer's authority must match the program's upgrade authority.
|
||||||
|
|
||||||
|
Buffers also support `show` and `dump` just like programs do.
|
||||||
|
|
||||||
|
### Non-redeployable programs
|
||||||
|
|
||||||
|
Using `solana program ...` utilizes Solana's upgradeable loader, but there is
|
||||||
|
another way to deploy programs using the original on-chain loader.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
solana deploy <PROGRAM_FILEPATH>
|
||||||
|
```
|
||||||
|
|
||||||
|
Programs deployed with `solana deploy ...` are not upgradeable and are not
|
||||||
|
compatible with the `solana program ...` commands.
|
@ -5,13 +5,13 @@ title: "Overview"
|
|||||||
An [app](terminology.md#app) interacts with a Solana cluster by sending it
|
An [app](terminology.md#app) interacts with a Solana cluster by sending it
|
||||||
[transactions](transactions.md) with one or more
|
[transactions](transactions.md) with one or more
|
||||||
[instructions](transactions.md#instructions). The Solana [runtime](runtime.md)
|
[instructions](transactions.md#instructions). The Solana [runtime](runtime.md)
|
||||||
passes those instructions to [programs](terminology.md#program) deployed by app developers
|
passes those instructions to [programs](terminology.md#program) deployed by app
|
||||||
beforehand. An instruction might, for example, tell a program to transfer
|
developers beforehand. An instruction might, for example, tell a program to
|
||||||
[lamports](terminology.md#lamports) from one [account](accounts.md) to another
|
transfer [lamports](terminology.md#lamports) from one [account](accounts.md) to
|
||||||
or create an interactive contract that governs how lamports are transferred.
|
another or create an interactive contract that governs how lamports are
|
||||||
Instructions are executed sequentially and atomically for each transaction. If
|
transferred. Instructions are executed sequentially and atomically for each
|
||||||
any instruction is invalid, all account changes in the transaction are
|
transaction. If any instruction is invalid, all account changes in the
|
||||||
discarded.
|
transaction are discarded.
|
||||||
|
|
||||||
To start developing immediately you can build, deploy, and run one of the
|
To start developing immediately you can build, deploy, and run one of the
|
||||||
[examples](developing/deployed-programs/examples.md).
|
[examples](developing/deployed-programs/examples.md).
|
Reference in New Issue
Block a user